问题描述
在尝试测试某些代码时,我尝试访问子类(__var)的名称混杂属性时遇到了一些意外行为。没得到孩子的价值,我以为我得到了父类的__var。
最终编辑:子对象访问其自身的变量版本,该名称与父对象的名称(而不是其自身的名称)成对。现在可以了解以前的意外行为。
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的名称更改发生在解释器“读取”方法(可能不是正确的术语)时,而不是在调用方法时。测试证明了后台发生的过程。
首次遇到__var时,它位于test_parent的主体内,并且被名称拼凑:
class test_parent(object):
__var = 1
成为:
class test_parent(object):
_test_parent__var = 1
在__var
中遇到test_child
成为_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()
分配给测试代码3
就会返回b.__class__._test_parent__var
的原因,因为那是getvar方法访问的值。