Py学习  »  Python

具有私有继承的Python名称损坏

joesdiner • 5 年前 • 1889 次点击  

我知道 Python name mangling ,但在使用mutliple继承时遇到意外行为。例如:

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'

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

有人能告诉我这里发生了什么事吗?我希望这些类定义的行为都一样。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/53577
 
1889 次点击  
文章 [ 1 ]  |  最新文章 5 年前
chepner
Reply   •   1 楼
chepner    6 年前

在你最初的定义中, class D(C, A) ,呼叫 D.__init__ 决心 C.__init__ A.__init__ 从来没有打过电话 __foo 属性从未创建。

在修改后的定义中( class D(A, C) ),呼叫 决心 A、 初始化__ __福 .

调用父构造函数以确保实例正确初始化是很重要的,而且与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()

只要 全部的 超级的 正确地说,每个方法都将被调用一次,不管方法的解析顺序是D1 [C, B, A, object] 或D2 [A, C, B, object]