带有双下划线的 Python 方法名称被覆盖了吗?
- 2025-04-10 09:47:00
- admin 原创
- 22
问题描述:
看一下这个。请注意,该类B
覆盖了A
的a()
方法。
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()
?
有啥__special__
关于 的吗__a
?
更新:阅读 Sean 的回答后,我想看看是否可以覆盖名称混乱的方法并得到以下结果:
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()
解决方案 1:
具有 __* 模式的关键字是类私有名称。
http://docs.python.org/reference/lexical_analysis.html#reserved-classes-of-identifiers
引用:
此类别中的名称在类定义上下文中使用时,将被重写为使用混乱形式,以帮助避免基类和派生类的“私有”属性之间的名称冲突
私人名称修改(强调添加):
私有名称修改:如果类定义中文本出现的标识符以两个或多个下划线字符开头,并且不以两个或多个下划线结尾,则它被视为该类的私有名称。私有名称在生成代码之前会转换为更长的形式。转换过程会在名称前面插入类名,删除前导下划线,并在类名前面插入一个下划线。例如,
__spam
名为 Ham 的类中的标识符将转换为_Ham__spam
。此转换与使用该标识符的句法上下文无关。如果转换后的名称非常长(超过 255 个字符),则可能会发生实现定义的截断。如果类名仅由下划线组成,则不会进行转换。
http://docs.python.org/reference/expressions.html#atom-identifiers
这意味着在幕后,B.__a()
被转化成类似B._B__a()
解决方案 2:
In [1]: class A(object):
...: def __init__(self):
...: self.a()
...: def a(self):
...: print "A.a()"
...:
...: __str__ = a
...:
In [2]: class B(A):
...: def __init__(self):
...: super(B, self).__init__()
...: def a(self):
...: print "B.a()"
...:
...:
In [3]: b = B()
print str(b)
A.a()
您需要在B__str__
中再次声明。
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD