【问题标题】:@abstractmethod works just fine without metaclass=ABCMeta when it shouldn't@abstractmethod 在不应该使用 metaclass=ABCMeta 的情况下工作得很好
【发布时间】:2018-08-24 03:13:23
【问题描述】:

考虑这段代码

from abc import ABCMeta, abstractmethod

class C():
    @abstractmethod
    def my_abstract_method(self):
        print('foo')

class D(C):
    pass

x = C()
y = D()

mypy 不允许 xy 给我一个

test.py:13: error: Cannot instantiate abstract class 'C' with abstract attribute 'my_abstract_method'
test.py:15: error: Cannot instantiate abstract class 'D' with abstract attribute 'my_abstract_method'

我正在使用 mypy 0.570python 3.6.3 进行测试

但是,文档说我需要设置 metaclass=ABCMeta 才能工作。我错过了什么?

【问题讨论】:

  • 哪个 Python 版本?我无法在 2.7.x 和 3.4.3 上重现此行为
  • 更新问题。我收到了 mypy 版本 0.570 的错误。顺便说一句,无论我是否应用metaclass=ABCMeta,我都不会直接收到 python 错误。所以mypy 是唯一能真正帮助我发现这个错误的工具。
  • mypypython 做了两件非常不同的事情。 mypy 是一个静态 分析器,如果您的代码的 中存在@abstractmethod,则可以随意假设您忘记使用ABCMetapython 只是解释代码,没有ABCMeta,它没有理由对@abstractmethod 填充的方法列表做任何事情。 (事实上​​,在 runtime 方法本身并没有证据表明它被 修饰过。)
  • @chepner 是的,这是真的。碰巧我注意到mypy 在没有设置metaclass 的情况下捕获了错误,并且我没有进一步检查python 的实际作用。我只是停在那里想知道为什么mypy 在我认为不应该出现错误时会捕获错误。感谢您提供背景信息!

标签: python abc


【解决方案1】:

好的,原来没有metaclass=ABCMeta 只有mypy 会捕获错误,而使用metaclass=ABCMeta mypypython 都会捕获错误。

见:

from abc import abstractmethod

class C():
    @abstractmethod
    def my_abstract_method(self):
        print('foo')

class D(C):
    pass

x = C()
y = D()

$ mypy test.py 
test.py:13: error: Cannot instantiate abstract class 'C' with abstract attribute 'my_abstract_method'
test.py:15: error: Cannot instantiate abstract class 'D' with abstract attribute 'my_abstract_method'

但是

$ python3 test.py
$

尽管如此,python 也会捕获错误。

from abc import ABCMeta, abstractmethod

class C(metaclass=ABCMeta):
    @abstractmethod
    def my_abstract_method(self):
        print('foo')

class D(C):
    pass

x = C()

y = D()


$ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    x = C()
TypeError: Can't instantiate abstract class C with abstract methods my_abstract_method

【讨论】:

    猜你喜欢
    • 2017-09-17
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多