属性名称与 parent class 名称(在第一次解析时)而不是 child class 名称(在 instantiation/call)混淆

Attribute name mangled with parent class name (at first parsing) instead of child class name (at instantiation/call)

我 运行 在尝试测试某些代码时遇到了一些意外行为,我试图访问 child class 的 name-mangled 属性(__var).我没有得到 child 的值,而是得到了 parent class 的 __var。

最终编辑:child object 访问它自己的变量版本,name-mangled 和 parent'的名字而不是它自己的名字。现在可以理解以前的意外行为。

class test_parent(object):
    __var = 1

    def getvar(self):
        a = self.__class__.__var
        return a

class test_child(test_parent):
    __var = 2

a = test_parent()
b = test_child()
b.__class__._test_parent__var = 3

print(a.getvar())                       # Prints 1, as expected
print(b.__class__._test_child__var)     # Prints 2, as expected
print(b.__class__._test_parent__var)    # Prints 3, as expected
print(b.getvar())                       # Prints 3

在评论的帮助下回答:

Python 的 name-mangling 发生在方法被解释器 'read' 时(可能不是正确的术语),而不是在它被调用时。测试证明了后台发生的过程。

第一次遇到__var时,它在test_parent的body里面,是name-mangled:

class test_parent(object):
    __var = 1

变为:

class test_parent(object):
    _test_parent__var = 1

test_child中遇到__var时会发生类似的事情,变成_test_child__var。之前意想不到的行为是因为getvar内部发生了同样的事情。

class test_parent(object):
    ...
    def getvar(self):
        ...
        a = self.__class__.__var

变为:

class test_parent(object):
    ...
    def getvar(self):
        ...
        a = self.__class__._test__parent_var

这就是为什么测试代码b.getvar() returns 3一旦b.__class__._test_parent__var被赋值给它,因为那是getvar方法访问的值。