2009-07-16 16 views
14

这就是我想在Python做:Python的继承和调用父类的构造

class BaseClass: 
    def __init__(self): 
     print 'The base class constructor ran!' 
     self.__test = 42 

class ChildClass(BaseClass): 

    def __init__(self): 
     print 'The child class constructor ran!' 
     BaseClass.__init__(self) 

    def doSomething(self): 
     print 'Test is: ', self.__test 


test = ChildClass() 
test.doSomething() 

导致:

AttributeError: ChildClass instance has no attribute '_ChildClass__test' 

是怎么回事?为什么不按照我的预期工作?

+0

调用基类.-- init--在你做其他事情之前为了将来的参考, – 2009-07-16 21:29:50

回答

20

在Python文档:

私人名称重整:当该文本方式发生在类定义的标识符开始具有两个或多个下划线字符,并在两个或多个下划线并没有结束,它被认为是该类别的私人名称。在为其生成代码之前,专用名称是转换为更长的形式。转换将类名插入名称前面,删除前导下划线,并在类名前插入一个下划线。例如,发生在名为Ham的类中的标识符__spam将被转换为_Ham__spam。这种转换独立于使用标识符的语法上下文。如果转换的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名只包含下划线,则不进行转换。

所以你的属性不被命名为__test_BaseClass__test

但是你不应该依赖于使用self._test,而不是大多数Python开发者都知道,该属性是一个类的内部部分,而不是公共接口。

+1

啊......那么如果我需要扩展一个类,那么访问那些私有成员是否存在“正确”或“pythonic”方式?那是使用这种语法? – 2009-07-16 19:43:09

+0

@Keith:这是一个比Python问题更多的面向对象问题。通过访问超类的私有成员,您正在破解封装并在类之间创建非常强大的依赖关系。即使公共接口保持不变,超类也不再允许改变其内部工作。总之:不要这样做:) – 2009-07-16 19:51:24

3

双重下划线变量可以被视为“私人”。他们受到班级名称的影响,以保护多个基类免于凌驾其他成员。

如果您希望您的属性被其他开发者视为私有属性,请使用单个下划线。

5

您可以使用Python的自省设施来获取您正在查找的信息。 一个简单的目录(测试)会给你

['_BaseClass__test', '__doc__', '__init__', '__module__', 'doSomething'] 

注意 '_BaseClass__test'。这就是你要找的。

检查this了解更多信息。