Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Python-为多个父类调用_init_Python 3.x - Fatal编程技术网

Python 3.x Python-为多个父类调用_init

Python 3.x Python-为多个父类调用_init,python-3.x,Python 3.x,编辑:我在Python 3上 我有一个类X,它扩展了Y和Z: class X(Y, Z): def __init__(self): # Call Y's __init__ # Call Z's __init pass 我需要在Y和Z上调用\uuuuuu init\uuuuuu,从X上的\uuuuuu调用。最好的方法是什么 这完全取决于Y和Z是否设计为与多重继承协同工作。如果是,那么您应该能够只使用super: class X(Y, Z): def __i

编辑:我在Python 3上

我有一个类
X
,它扩展了
Y
Z

class X(Y, Z):
    def __init__(self):
    # Call Y's __init__
    # Call Z's __init
    pass

我需要在
Y
Z
上调用
\uuuuuu init\uuuuuu
,从
X
上的
\uuuuuu
调用
。最好的方法是什么

这完全取决于
Y
Z
是否设计为与多重继承协同工作。如果是,那么您应该能够只使用
super

class X(Y, Z):
    def __init__(self):
        super().__init__()
当我说
Y
Z
需要设计为与多重继承协同工作时,我的意思是它们还必须在
\uuuuuu init\uuuu
方法中调用super:

class Y:
    def __init__(self):
        print('Y.__init__')
        super().__init__()

class Z:
    def __init__(self):
        print('Z.__init__')
        super().__init__()
它们还应该有一些处理不同参数的策略,因为类(尤其是构造函数)在接受哪些关键字参数方面经常不同。在这一点上,有必要阅读并理解一些关于超级计算机的常见习语和陷阱

如果您不知道
Y
Z
是否设计用于合作多重继承,那么最安全的方法是假设它们不是


如果这些类不是为协同多重继承而设计的,那么您需要开始轻举妄动(您处于危险境地)。您可以分别调用每个
\uuuuu init\uuuu

class X(Y, Z):
    def __init__(self):
        Y.__init__(self)
        Z.__init__(self)

但实际上,最好不要使用多重继承,而是选择不同的范式(例如组合)。

一般来说,没有其他方法可以直接调用
Y.\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuo(self)
。这是确保两个构造函数至少调用一次的唯一方法

但是,在某些奇怪的情况下(或正常情况,取决于您如何看待),这可能会导致非常不直观的结果,其中多次调用基本构造函数:

class Y:
    def __init__(self):
        print('Y')
        super().__init__()

class Z:
    def __init__(self):
        print('Z')
        super().__init__()

class X(Y, Z):
    def __init__(self):
        print('X')
        Y.__init__(self)
        Z.__init__(self)

X()
导致

X
Y
Z
Z
因此在这种情况下,
super()。
X
中的
初始化
(而不是两个
。\uu初始化
调用)看起来很自然,可以正常工作。但是,如果
Y
Z
不调用
super()。\uuuu init\uuuuu()
,它将失败。在这种情况下,您将只调用一个构造函数

所以一般来说,如果不知道基类的实现,就无法正确地解决问题


YARtAMI=避免多重继承的另一个原因是这是Python 2还是Python 3?我使用Python 3。这是另一个原因,为什么多重继承是不好的,那么您如何在这种不好的实践中询问最佳实践呢?好的,我删除了关于最佳实践的部分。现在你的建议是什么?在我的例子中,父母是-
threading.Thread
logging.Handler
-我如何检查他们是否被设计为在多重继承中协同工作?据我所知,不是。@masnun你需要问自己的问题是:为什么你想从他们两个继承?你在混合不相关的概念。使用一个类并将它们都作为字段(或其他干净模式)会更干净。@mgilson我猜
Handler
也不使用
super
。我可以在它自己的
中看到它调用
filter.\uuuu init\uuuu(self)
。感谢您的解释。让我们假设
Y
也有一个基类(
Q
),并且
Y
调用
super()。\uuu init\uu()
,以确保它(隐式)调用
Q.\uu init\uu()
。根据方法解析顺序,
Y
super()。如果
Z.\uuuuu init\uuuuu
super
s,那么您将调用
Z.\uuuuu init\uuuuuu
两次(在此处调用一次,以后显式调用一次)。如果
Z.\uuuuu init\uuuu
没有
super
,那么您可能会完全跳过
Q.\uuuuu init\uuuu
。感谢您的详细解释。在我的例子中,没有一个父类有任何共同的祖先。我已经更新了答案。是否有任何解释可以解释为什么Y中的第一个调用
super()。\uuu init\uu()
会触发Z.\uu init\uu()???我知道Y和Z继承自
对象
,所以我不明白为什么第一个“Z”会打印在屏幕上