带有双下划线的 Python 方法名称是否被覆盖? [英] Python method name with double-underscore is overridden?

查看:32
本文介绍了带有双下划线的 Python 方法名称是否被覆盖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Take a look at this. Note that class B overrides A's a() method.

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().

Now, take a look at this. Note that the method now being overridden is __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()?

Can anyone explain why A.__a() is called instead of B.__a()?

任何关于__a__special__?

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

Update: After reading Sean's answer I wanted to see if I could override the name mangled method and got this result:

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()

推荐答案

具有 __* 模式的关键字是类私有名称.

keywords with a pattern of __* are class private names.

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 name mangling (emphasis added):

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

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()

This means that behind the scenes, B.__a() is transformed to something like B._B__a()

这篇关于带有双下划线的 Python 方法名称是否被覆盖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆