我有以下课程:
class A:
def __init__(self):
#base constructor implementation
pass
def __virt_method(self):
raise NotImplementedError()
def public_method(self):
self.__virt_method()
class B(A):
def __init(self):
A.__init__(self)
#derived constructor implementation
pass
def __virt_method(self):
#some usefull code here
pass
我正在尝试像这样使用它,假设要调用重写的方法:
b = B()
b.public_method()
但是我反而得到了NotImplementedError
(我做错了什么还是Python(2?)问题?我知道Python 2已过时,最好使用Python 3,但是现在我真的别无选择。
答案 0 :(得分:6)
这是由于name mangling造成的。 Python内部会将__virt_method
重命名为基类中的_A__virt_method
,并在派生类中将其重命名为_B__virt_method
:
任何形式为
__spam
的标识符(至少两个前导下划线,最多一个尾随下划线)在文本上都被替换为_classname__spam
,其中classname是当前类名,前导下划线被去除了
将方法重命名为_virt_method
(只有一个下划线),它将起作用:
class A:
def __init__(self):
# base constructor implementation
pass
def _virt_method(self):
raise NotImplementedError()
def public_method(self):
self._virt_method()
class B(A):
def __init(self):
A.__init__(self)
# derived constructor implementation
pass
def _virt_method(self):
# some useful code here
pass
答案 1 :(得分:4)
问题在于,名称以__
开头的方法(例如__virt_method
)的名称混乱。基本上,根据它们所在的类,它们的名称会转换为A__virt_method
或B__virt_method
。
如果将方法重命名为_virt_method
,一切将按预期运行
答案 2 :(得分:1)
如果任何变量以'__'开头,则python会理解此变量实际上是私有变量,因此它使用名为name mangling
的概念来防止直接访问该变量。如果变量以“ _”开头,则仅供内部使用或仅限于本地范围(from something import *
时不会加载)。
In [60]: class A(object):
...: def __init__(self):
...: self.__name = 'Premkumar'
...:
In [61]: premkumar = A()
In [62]: premkumar.__dict__
Out[62]: {'_A__name': 'Premkumar'}