是否覆盖带双下划线的Python方法名?
看看这个。 请注意,类是否覆盖带双下划线的Python方法名?,python,Python,看看这个。 请注意,类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): .
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()
这并不奇怪
现在,看看这个。
请注意,现在被重写的方法是\uu a()
这种行为使我吃惊
有人能解释为什么调用A.\uu A()
而不是B.\uu A()
关于\uuuu a
有什么特别的吗
更新:
在阅读了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()
模式为_*的关键字是类私有名称 引述: 当在类定义的上下文中使用此类别中的名称时,会重新编写以使用损坏的形式,以帮助避免基类和派生类的“私有”属性之间的名称冲突 私有名称mangling(增加强调): 私有名称混乱:当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。在为私有名称生成代码之前,会将其转换为更长的形式。转换将在名称前面插入类名,删除前导下划线,并在类名前面插入一个下划线例如,出现在名为Ham的类中的标识符
\uu spam
将转换为\u Ham\uu spam
。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名只包含下划线,则不进行任何转换
这意味着在幕后,B.\uuu a()
被转换为类似于B.\uu B\uu a()
您需要在B中再次声明
\uuuu str\uuuu
,在手册中查找的正确位置正是我要查找的位置。谢谢。我不确定这里发生的是同一件事,因为瓦特没有像瓦特那样被弄坏。
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()
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()