Python 无法实例化抽象类......使用抽象方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31457855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:01:42  来源:igfitidea点击:

Can't instantiate abstract class ... with abstract methods

pythonabstract-classabcsix

提问by josuebrunel

I'm working on a kind of lib, and for a weird reason i have this error.

我正在开发一种库,但出于一个奇怪的原因,我遇到了这个错误。

  • Hereis my code. Of course @abc.abstractmethod have to be uncommented
  • Hereare my tests
  • 是我的代码。当然@abc.abstractmethod 必须取消注释
  • 是我的测试

Sorry couldn't just copy and paste it

抱歉不能只是复制和粘贴它

I went on the basis that the code below works

我的基础是下面的代码有效

test.py

测试文件

import abc
import six

@six.add_metaclass(abc.ABCMeta)
class Base(object):

    @abc.abstractmethod
    def whatever(self,):
        raise NotImplementedError

class SubClass(Base):

    def __init__(self,):

        super(Base, self).__init__()
        self.whatever()

    def whatever(self,):
        print("whatever")

In the python shell

在 python 外壳中

>>> from test import *
>>> s = SubClass()
whatever

Why for my rostermodule i'm having this error

为什么我的名册模块出现此错误

Can't instantiate abstract class Player with abstract methods _Base__json_builder, _Base__xml_builder

Thanks in advance

提前致谢

采纳答案by Anand S Kumar

Your issue comes because you have defined the abstract methods in your base abstract class with __(double underscore) prepended. This causes python to do name manglingat the time of definition of the classes.

您的问题出现是因为您已经在基础抽象类中定义了带有__(双下划线)前缀的抽象方法。这会导致 python在定义类时进行名称修改

The names of the function change from __json_builderto _Base__json_builderor __xml_builderto _Base__xml_builder. And this is the name you have to implement/overwrite in your subclass.

函数名称从__json_builder_Base__json_builder__xml_builder变为_Base__xml_builder。这是您必须在子类中实现/覆盖的名称。

To show this behavior in your example -

要在您的示例中显示此行为 -

>>> import abc
>>> import six
>>> @six.add_metaclass(abc.ABCMeta)
... class Base(object):
...     @abc.abstractmethod
...     def __whatever(self):
...             raise NotImplementedError
...
>>> class SubClass(Base):
...     def __init__(self):
...             super(Base, self).__init__()
...             self.__whatever()
...     def __whatever(self):
...             print("whatever")
...
>>> a = SubClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class SubClass with abstract methods _Base__whatever

When I change the implementation to the following, it works

当我将实现更改为以下内容时,它会起作用

>>> class SubClass(Base):
...     def __init__(self):
...             super(Base, self).__init__()
...             self._Base__whatever()
...     def _Base__whatever(self):
...             print("whatever")
...
>>> a = SubClass()
whatever

But this is very tedious , you may want to think about if you really want to define your functions with __(double underscore) . You can read more about name mangling here.

但这很乏味,你可能要考虑一下你是否真的想用__(double underscore)定义你的函数。您可以在此处阅读有关名称修改的更多信息。