为什么 mypy 试图在 Python 中实例化我的抽象 class?

Why is mypy trying to instantiate my abstract class in Python?

如果我有这样的 Python 模块:

from abc import ABC, abstractmethod

class AbstractClass(ABC):
    @abstractmethod
    def method(self):
        pass

class ConcreteClass1(AbstractClass):
    def method(self):
        print("hello")

class ConcreteClass2(AbstractClass):
    def method(self):
        print("hello")

class ConcreteClass3(AbstractClass):
    def method(self):
        print("hello")

classes = [
    ConcreteClass1,
    ConcreteClass2,
    ConcreteClass3,
]

for c in classes:
    c().method()

然后我用 mypy test.py 击中它,我明白了:

test.py:27: error: Cannot instantiate abstract class "AbstractClass" with abstract attribute "method"

虽然代码运行没有任何问题,但我看不出逻辑有任何问题。 我绝不会尝试直接实例化 AbstractClass

我注意到一些奇怪的行为:

如果我不使用循环,而是这样做:

...
ConcreteClass1().method()
ConcreteClass2().method()
ConcreteClass3().method()

mypy 很开心。

此外,如果我在循环中执行 2:

而不是 3 类
classes = [
    ConcreteClass1,
    ConcreteClass2,
    #ConcreteClass3,
]

for c in classes:
    c().method()

mypy 对此也很满意。 这是怎么回事?这是一个 mypy 错误吗?如果是这样,我可以告诉 mypy 忽略这个“问题”吗?

问题类似于 mypy issues with abstract classes and dictionaries - 由于某种原因,mypy 无法在列表中没有类型注释的情况下正确地进行类型检查:

classes: list[Type[AbstractClass]] = [
    ConcreteClass1,
    ConcreteClass2,
    ConcreteClass3,
]

(如果您使用 Python 3.8 或更低版本,请将 list 更改为 List

您可能想在 mypy Github.

上针对此错误提交问题