python中getattr(self, '__a')和self.__a有什么区别?
我之前以为它们是一样的,直到我运行了这段代码:
class B(object):
def show(self):
self.__a = "test"
print "B"
def this_b(self):
print "this_b"
print self.__a
print getattr(self, '__a') #exception
class C(B):
def show(self):
print "C"
# B.show(self)
super(C, self).show()
def call(self):
print "call"
self.show()
self.this_b()
# print self.__a
C().call()
这段代码引发了一个错误,提示 AttributeError: 'C' object has no attribute '__a'
,但是为什么会这样呢?
1 个回答
12
这是因为有一个叫做 私有名称改名的规则。
私有名称改名:当一个在类定义中出现的名字以两个或更多的下划线开头,并且不以两个或更多的下划线结尾时,这个名字就被认为是该类的私有名称。私有名称在生成代码之前会被转换成一个更长的形式。这个转换会把类名(去掉前面的下划线,并在前面加一个下划线)放到名字前面。例如,在一个叫做
Ham
的类中出现的__spam
会被转换成_Ham__spam
。这个转换和名字使用的上下文没有关系。如果转换后的名字非常长(超过255个字符),可能会被截断。如果类名只有下划线,那么就不会进行任何转换。
当你执行
self.__a
时,私有名称改名会自动处理。但是当你执行
print getattr(self, '__a')
时,你需要手动处理,就像这样
print getattr(self, '_B__a')
# test