python - 具有不同初始化参数的基类的方法解析顺序

标签 python class oop inheritance method-resolution-order

我想了解 Python 中的 MRO。虽然这里有各种各样的帖子,但我并没有特别得到我想要的。考虑从 BaseClass 派生的两个类 AB,每个类都有一个采用不同参数的 __init__

class BaseClass(object):
    def __init__(self):
        print "I am the base class"

class A(BaseClass):
    def __init__(self, something, anotherthing):
        super(A, self).__init__()
        self.something = something
        self.anotherthing = anotherthing
    def methodsA(self):
        ...

class B(BaseClass):
    def __init__(self, someOtherThing):
        super(B, self).__init__()
        self.someOtherThing = someOtherThing 
    def methodsB(self):
        ...

问题是,如果我需要从 AB 派生第三类 C,我该如何初始化 __init__,如果必须的话?我可以安全地从 BA 派生 C

   class C(A,B):
     def __init__(self, something, anotherthing, someOtherThing):
         super(C, self).__init__(something, anotherthing, someOtherThing)

上面的实现给我一个错误。

最佳答案

正如 jonrsharpe 在他的帖子末尾提到的,这是我遇到的最好的方式 处理这种情况的方法是接受 **kwargs 并提取 显式命名参数。

class BaseClass(object):
    def __init__(self, **kwargs):
        print("BaseClass.__init__({},{})".format('', kwargs))
        super(BaseClass,self).__init__(**kwargs)            

class A(BaseClass):
    def __init__(self, **kwargs):
        print("A.__init__({},{})".format('', kwargs))

        a = kwargs.pop('something')
        super(A,self).__init__(**kwargs)

class B(BaseClass):
    def __init__(self, **kwargs):
        print("B.__init__({},{})".format('', kwargs))       

        b = kwargs.pop('anotherthing')
        super(B,self).__init__(**kwargs)


class C(A, B):
    def __init__(self, **kwargs):
        print("C.__init__({},{})".format('', kwargs))

        super(C,self).__init__(**kwargs)


c = C(something=1,anotherthing='a')

需要提取的参数应该以命名方式传递,所以它们出现在kwargs中。

您甚至可以像示例中一样通过省略 *args 来显式仅接受命名参数,因此如果您忘记了,就会遇到 TypeError。

编辑:

经过一段时间的思考,我意识到我的示例非常适合您的示例,如果您引入另一个类或更改继承,它可能会中断。有两件事应该解决以使其更通用:

BaseClass 不调用 super。

对于示例,这无关紧要,但如果引入了另一个类,则 MRO 可能会更改,以便在 BaseClass 之后有一个类,因此它应该调用 super。这就引出了第二个问题:

object.__init__() 不带参数

如果我们想让类(特别是 BaseClass)安全地放入一个通用的多重继承结构中,在这个结构中它的 super 调用可能被分派(dispatch)到另一个类 对象,我们需要从 kwargs 中弹出参数当我们消费它们时。

但这增加了另一个复杂性,因为它要求没有两个 __init__ 函数共享相同的参数名称。我想得出的结论是让多重继承以一种通用的方式工作是很困难的。

这是一篇关于一些细节的有趣文章(通过谷歌找到):article

关于python - 具有不同初始化参数的基类的方法解析顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21862357/

相关文章:

python - 将函数从一个文件导入到另一个文件会出现错误

class - Flutter Equatable Class 属性必须全部为 final

c++ - C++ 模块之间的数据传输

java - 处理这个问题的正确设计是什么?

c# - 为新对象实例设置参数

python - Python 中的 Speex

python - Docker compose 安装需求.txt

python - 根据数据框中列表对象的内容选择 Pandas 数据框

python - 如何在实例化时有条件地将 mixin 添加到当前类中?

JQuery 从存储在变量中的对象中删除和添加类