我知道Python name mangling,但是在使用多重继承时遇到了意外的行为。例如:
class A(object):
def __init__(self):
self.__foo=1
def bar(self):
return self.__foo
class B(object):
pass
class C(B):
def __init__(self):
self.test=1
class D(C,A):
pass
print D().bar()
出现错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in bar
AttributeError: 'D' object has no attribute '_A__foo'
但是,如果我将“ D”的定义更改为:
class D(A,C):
pass
有效。输出:
1
此外,如果我从类“ C”中删除所有成员变量,则D作品的定义都将
class C(B):
pass
class D1(A, C):
pass
class D2(C, A):
pass
print D1().bar()
print D2().bar()
输出:
1
1
有人能启发我这里发生了什么吗?我希望这些类定义中的任何一个都具有相同的行为。
答案 0 :(得分:3)
在您的原始定义class D(C, A)
中,对D.__init__
的调用被解析为C.__init__
,因此从未调用A.__init__
并且从未创建__foo
属性
在修改后的定义(class D(A, C)
中,对D.__init__
的调用被解析为A.__init__
,这确实设置了__foo
。
调用父构造函数以确保实例已正确初始化很重要,并且与Java不同,必须显式调用父构造函数。
对于多重继承,如果使用super
以确保调用每个类的__init__
方法,则问题会更少。
class A(object):
def __init__(self):
super(A, self).__init__()
self.__foo = 1
def bar(self):
return self.__foo
class B(object):
pass
class C(B):
def __init__(self):
super(C, self).__init__()
self.test = 1
class D1(C,A):
pass
class D2(A,C):
pass
# Both will print 1
print D1().bar()
print D2().bar()
只要所有类正确使用super
,每个方法将被调用一次,无论方法解析顺序是D1的[C, B, A, object]
还是D2的[A, C, B, object]
。