如何使用Python中从接口继承的第二个父类方法?

Dan*_*ier 8 oop design-patterns python-3.x

我正在尝试实现一个接口,并且该接口由两个具体类采用,并且class Firstclass Second我有另一个类将这两个类作为父类class CO。根据class CO标志来决定返回两个继承类中的哪一个,以便使用它们的实现。

from abc import ABC, abstractmethod

class common(ABC):
    @abstractmethod
    def firstfunction(self):
        pass 

    @abstractmethod
    def secondfunction(self):
        pass

class First(common):
    def __init__(self)-> boto3:
        self.ert = "danish"
        # self.username = kwargs["username"]
        # self.password = kwargs["password"]

        print("Inside First function")

    def firstfunction(self):
        print("My implementation of the first function in FIRST CLASS")

    def secondfunction(self):
        print("My implementation of the second function in FIRST CLASS")   

class Second(common):
    def __init__(self):
        self.rty = "pop"
        # self.session_id = kwargs["session_id"]

        print("Inside Second function")

    def firstfunction(self):
        print("My implementation of the first function in SECOND CLASS")

    def secondfunction(self):
        print("My implementation of the second function in SECOND CLASS")

class CO(First, Second):
    def __init__(self):
        self.inst = self.jo()

    def jo(self):
        a = True 

        if a:
            main_object = First()
            return main_object
        else:
            main_object = Second()
Run Code Online (Sandbox Code Playgroud)

我正在实例化并调用方法

mymainclass = co()
objt = mymainclass

objt.firstfunction()
objt.secondfunction()
Run Code Online (Sandbox Code Playgroud)

所以我的条件是,如果在类flag a = TrueCO,则应该使用方法的具体类First实现,我们应该得到如下输出:

第一个函数内部

我在 FIRST CLASS 中实现的第一个函数

我在 FIRST CLASS 中实现第二个函数

如果flag a = False在类中CO,那么应该使用具体类Second,我们应该得到如下输出:

在第二个函数内部

我在 FIRST CLASS 中实现的第一个函数

我在 FIRST CLASS 中实现第二个函数

从给定的代码中,我得到了该标志的以下输出a = False

在第二个函数内部

我在 FIRST CLASS 中实现的第一个函数

我在 FIRST CLASS 中实现第二个函数

有人能让这段代码工作吗?我究竟做错了什么?我知道我可以创建一个函数,将这两个类作为变量,然后根据条件返回我想要的内容。但我想使用类来实现同样的目的

Boo*_*boo 6

我不会COFirst或继承 class Second,因为您希望最终得到一个作为classFirst class实例的对象Second。最直接的方法是定义方法,__new__这将使您能够更好地控制实例创建。

保持所有代码相同(修复明显的错误,例如boto3未定义之后)并更改类,CO如下所示:


class CO:
    def __new__(cls):
        a = True

        if a:
            main_object = First()
        else:
            main_object = Second()
        return main_object

o = CO()
print(type(o))
Run Code Online (Sandbox Code Playgroud)

印刷:

Inside First function
<class '__main__.First'>
Run Code Online (Sandbox Code Playgroud)

如果您想更好地参数化实例创建(并简化 中的代码__new__),则将变量a作为参数CO

class CO:
    def __new__(cls, a):
        return First() if a else Second()

o = CO(False)
print(type(o))
Run Code Online (Sandbox Code Playgroud)

印刷:

Inside Second function
<class '__main__.Second'>
Run Code Online (Sandbox Code Playgroud)

您可以选择将类CO作为common其基类,以记录实例化此类会产生实现该common接口的实例。但这样做不会导致强制执行返回的实际类型__new__

class CO(common):
    def __new__(cls, a) -> common:
        # The Python interpreter is not type-checking what is returned:
        #return First() if a else Second()
        return []

o = CO(False)
print(type(o))
Run Code Online (Sandbox Code Playgroud)

印刷:

<class 'list'>
Run Code Online (Sandbox Code Playgroud)

您还可以用工厂函数替换 class CO

def common_factory(a):
    return First() if a else Second()

o = common_factory(False)
Run Code Online (Sandbox Code Playgroud)

笔记

如果您想确保从基类继承的类common必须重写两者firstfunction,并secondfunction更紧密地模拟其他面向对象语言中实现的纯接口,那么您应该定义这些函数,以便common它们引发NotImplementedError异常:

class common(ABC):
    @abstractmethod
    def firstfunction(self):
        raise NotImplementedError

    @abstractmethod
    def secondfunction(self):
        raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)

不幸的是,强制执行是在运行时完成的,这会带来意想不到的后果,而不是像其他面向对象语言那样在编译时完成。