带有双下划线的 Python 方法名称被覆盖?

标签 python

看看这个。 请注意,B 类会覆盖 Aa() 方法。

In [1]: class A(object):
   ...:     def __init__(self):
   ...:         self.a()
   ...:     def a(self):
   ...:         print "A.a()"
   ...:         
   ...:         

In [2]: class B(A):
   ...:     def __init__(self):
   ...:         super(B, self).__init__()
   ...:     def a(self):
   ...:         print "B.a()"
   ...:         
   ...:         

In [3]: b = B()
B.a()

没有惊喜。

现在,看看这个。 请注意,现在被覆盖的方法是 __a()

In [7]: class A(object):
   ...:     def __init__(self):
   ...:         self.__a()
   ...:     def __a(self):
   ...:         print "A.__a()"
   ...:         
   ...:         

In [8]: class B(A):
   ...:     def __init__(self):
   ...:         super(B, self).__init__()
   ...:     def __a(self):
   ...:         print "B.__a()"
   ...:         
   ...:         

In [9]: b = B()
A.__a()

这种行为让我很吃惊。

谁能解释为什么调用 A.__a() 而不是 B.__a()

关于__a的任何__special__

更新: 在阅读了 Sean 的回答后,我想看看是否可以覆盖 name mangled 方法并得到以下结果:

In [11]: class B(A):
   ....:     def __init__(self):
   ....:         super(B, self).__init__()
   ....:     def _A__a(self):
   ....:         print "B._A__a()"
   ....:         
   ....:         

In [12]: b = B()
B._A__a()

最佳答案

带有 __* 模式的关键字是类私有(private)名称。

http://docs.python.org/reference/lexical_analysis.html#reserved-classes-of-identifiers

引用:

Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes

私有(private)名称修改(强调):

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name in front of the name, with leading underscores removed, and a single underscore inserted in front of the class name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam. This transformation is independent of the syntactical context in which the identifier is used. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.

http://docs.python.org/reference/expressions.html#atom-identifiers

这意味着在幕后,B.__a() 被转换为类似 B._B__a()

关于带有双下划线的 Python 方法名称被覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6444576/

相关文章:

python - 具有合理默认值的必填字段

python - 将自定义刻度标签均匀地分布在颜色条上

python - 如何导入列表? ( python )

python - 如何使用 scapy 让端口显示为打开状态?

python - 无法将字符串从python发送到arduino

python - ClientForm.AmbiguityError : more than one control matching name

python - "TypeError: unhashable type: ' slice'"是什么意思?我该如何修复它?

Python:如何从 xlsx 文件中抓取数据的语法?

带有刻度标签的 Python PyQt4 slider

Python使用pandas每三行转列