[英]Python multiple inheritance of __new__ and __init__ with a string and second class
[英]Python “new style” multiple inheritance combined with multiple __init__ arguments
据我了解,如果所有类都使用“新样式”,则会发生这种情况:
class A(object):
def __init__(self):
print("Entering A")
super().__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super().__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super().__init__()
print("Leaving C")
c = C()
Entering C
Entering A
Entering B
Leaving B
Leaving A
Leaving C
在了解super
使用原始对象 ( c
) 的 MRO 之后,为什么Entering/Leaving
是这样的。 但是,如果我需要通过一些具体参数是什么A
和B
,而且在它的参数被按照接收顺序C
是不是类似于A
和B
:
class A(object):
def __init__(self, x1, x2):
print(f"Entering A [x1={x1}, x2={x2}]")
super().__init__()
print("Leaving A")
class B(object):
def __init__(self, y1, y2):
print(f"Entering B [y1={y1}, y2={y2}]")
super().__init__()
print("Leaving B")
class C(A, B):
def __init__(self, x1, y1, x2, y2):
print(f"Entering C [x1={x1}, y1={y1}, x2={x2}, y2={y2}]")
super().__init__()
print("Leaving C")
c = C('x1', 'y1', 'x2', 'y2')
我可以想到一整天都在传递kwargs
,但我觉得可能有更好的方法。
另外,如果B
是库的一部分,因此我们无法更改它并且它使用位置参数,而不是kwargs
呢? 在这种情况下,我该怎么办,因为我认为手动弄乱 MRO 不是一个好主意,但同时B
的构造函数不会接受kwargs
?
解决上述问题的正确方法是什么?
好的,这将不再适合评论,但这里似乎存在一些误解。
为了:
class C:
def __init__(self, arg1=1):
self.attr1 = arg1
class D(C):
def __init__(self, arg1):
super().__init__()
这将产生:
d = D(2)
print(d.attr1) # prints: 1
因为通过super().__init__()
我们调用了 parent 的构造函数,但是我们没有传递任何参数并且它以默认值运行。
或者引用文档来了解super 的作用:
返回一个代理对象,该对象将方法调用委托给类型的父类或兄弟类。 这对于访问在类中被覆盖的继承方法很有用。
即你“只”得到(可能绑定)解析的方法来调用。 不多也不少。 它不会整理您传递的任何参数。 所以你的例子实际上不起作用,因为父母的构造函数都需要一个实例和另外两个参数。
在你的例子中,你可以说:
class A:
def __init__(self, x1, x2):
print(f"Entering A [x1={x1}, x2={x2}]")
print("Leaving A")
class B:
def __init__(self, y1, y2):
print(f"Entering B [y1={y1}, y2={y2}]")
print("Leaving B")
class C(A, B):
def __init__(self, x1, y1, x2, y2):
print(f"Entering C [x1={x1}, y1={y1}, x2={x2}, y2={y2}]")
A.__init__(self, x1, x2)
B.__init__(self, y1, y2)
print("Leaving C")
因为您使用相应的特定参数调用每个特定的父构造函数。 文档(同一个地方,关于多继承的第二个常见用例的几段)还包含有关以下内容的提示:
好的设计要求此方法在每种情况下都具有相同的调用签名(因为调用顺序是在运行时确定的,因为该顺序会适应类层次结构的变化,并且因为该顺序可以包括在运行之前未知的兄弟类)。
也就是说,您获得一个代理来调用该方法……然后使用它的参数调用它……这必须是一个固定/稳定的集合,因为您无法预先确定通过该代理访问哪个方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.