为什么子类在本例中没有从python中的父类继承方法?

时间:2013-09-27 04:04:18

标签: python oop inheritance

我有以下代码。

class Foo(object):
     def __init__(self):
         self.__baz = 40
     def foo(self):
         print self.__baz

class Bar(Foo):
     def __init__(self):
         #super(Bar, self).__init__()
         self.__baz = 21
     def bar(self):
         print self.__baz

x = Bar()
x.foo()
x.bar()

我收到此错误:

Traceback (most recent call last):
  File "classes.py", line 15, in <module>
    x.foo()
  File "classes.py", line 5, in foo
    print self.__baz
AttributeError: 'Bar' object has no attribute '_Foo__baz'

为什么foo方法未在Bar中继承。

编辑:如果你打电话给被评论出来的超级网站,它可以正常工作。

4 个答案:

答案 0 :(得分:7)

双下划线属性基于当前/包含命名空间使其名称损坏。在函数foo中,当前命名空间为Foo,因此当python查找self.__baz时,由于名称修改方案,它实际上会查找self._Foo__baz。由于Foo中没有任何地方您实际设置了__baz属性,因此该类没有_Foo__baz属性(它具有_Bar__baz属性,因为您在self.__baz中设置了Bar Foo.__init__(self))内的方法。

当然,您可能已经注意到,如果您在Baz.__init__(直接或通过super)致电Foo.__init__,您会看到问题消失,因为{{1设置__baz(即_Foo__baz)。

答案 1 :(得分:3)

当您使用双下划线命名变量时,如python中的成员名称将被混淆。声明__baz会为您提供_Bar__baz成员。

class Bar(Foo):
 def __init__(self):
     #super(Bar, self).__init__()
     self.__baz = 21
 def bar(self):
     print self._Bar__baz

x = Bar()
x.bar()
>>> 21

答案 2 :(得分:2)

通过在__baz上使用初始双下划线,您请求“名称修改”以创建“私有”变量。它记录在这里:

http://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

如果您将名称从__baz更改为baz,则您的代码将如图所示。

答案 3 :(得分:0)

从python 3.6开始,我们现在可以使用__init_subclass__函数,该函数在Child的__init__之前自动调用。

class Foo(object):
     def __init_subclass__(self):
         self.__baz = 40
     def foo(self):
         print(self.__baz)

class Bar(Foo):
     def __init__(self):
         self.__baz = 21
     def bar(self):
         print(self.__baz)

x = Bar()
x.foo()
x.bar()

输出

40
21