无法使用抽象方法

时间:2015-07-16 15:00:36

标签: python abstract-class abc six

我正在开发一种lib,出于奇怪的原因我有这个错误。

  • Here是我的代码。当然 @ abc.abstractmethod必须取消注释
  • Here是我的测试

抱歉,无法复制并粘贴

我的基础是以下代码可以使用

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")

在python shell中

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

为什么我的名单模块我有这个错误

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

提前致谢

2 个答案:

答案 0 :(得分:27)

您的问题之所以出现,是因为您已在基础抽象类中定义了抽象方法,其前缀为__(双下划线)。这导致python在定义类时执行name mangling

该功能的名称从__json_builder更改为_Base__json_builder__xml_builder更改为_Base__xml_builder。这是您必须在子类中实现/覆盖的名称。

在示例中显示此行为 -

>>> 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

当我将实现更改为以下内容时,它可以正常工作

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

但这非常繁琐,你可能想要考虑一下你是否真的想用__(双下划线)定义你的函数。您可以阅读有关名称修改here的更多信息。

答案 1 :(得分:0)

此错误从python的源代码中弹出。这就是为什么我们看不到真正的例外情况。

PyErr_Format(PyExc_TypeError,        
             "Can't instantiate abstract class %s "
             "with abstract methods %U",
             type->tp_name,
             joined);

我从github克隆了python源代码。这是来自typeobject.c文件。