Python 继承与调用父类构造函数

14 投票
3 回答
27313 浏览
提问于 2025-04-15 12:57

我在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'

这是怎么回事?为什么这没有按照我预期的那样工作呢?

3 个回答

3

双下划线开头的变量可以被看作是“私有”的。这些变量会和类名一起被处理,主要是为了防止多个基类之间互相覆盖各自的成员。

如果你希望其他开发者把你的属性当作私有的,可以使用单下划线。

5

你可以使用Python的一些内省功能来获取你想要的信息。简单地输入 dir(test) 就能得到

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

注意到 '_BaseClass__test' 这个东西了吗?这就是你要找的。

想了解更多信息,可以查看 这个链接

20

来自Python文档:

私有名称处理:当一个在类定义中出现的标识符以两个或更多的下划线开头,并且不以两个或更多的下划线结尾时,它被认为是该类的私有名称。私有名称在生成代码之前会被转换为更长的形式。这个转换会在名称前面加上类名,并去掉开头的下划线,同时在类名前加一个下划线。例如,在一个名为Ham的类中出现的标识符__spam,会被转换为_Ham__spam。这个转换与标识符使用的语法上下文无关。如果转换后的名称非常长(超过255个字符),可能会进行截断。如果类名仅由下划线组成,则不会进行任何转换。

所以你的属性并不是叫__test,而是叫_BaseClass__test

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

撰写回答