如何调用派生类方法?

时间:2019-11-22 18:02:59

标签: python python-2.7

我有以下课程:

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,但是现在我真的别无选择。

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_methodB__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'}