Mypy 在类不执行协议时不会抱怨



我有以下代码。类A包含函数f。类B继承自A并重写此函数。我还有协议SupportsG,它充当实现函数g的所有类的结构超类型。我有类B显式继承这个协议:

from typing import Protocol
class SupportsG(Protocol):
def g(self) -> str: ...
class A:
def f(self) -> str:
return ""
class B(A, SupportsG):
def f(self) -> str:
return "test"
if __name__ == "__main__":
b = B()  

我的期望是mypy会抛出一个错误,因为类B没有实现函数g。但是,如果我运行mypy --strict,我不会得到任何错误。

我的理解差距在哪里?

def test(x: SupportsG):
pass  # whatever
a = A()
b = B()
test(a)  # mypy should complain
test(b)  # mypy should complain
class C:
def g(self) -> str:
return ""
c = C()
test(c)  # should be fine

您不需要从SupportsG继承您的类。

顺便说一句,Protocol的一个目的也是定义与kwargs的自定义功能接口,这在Callable中是不可能的,比如:

def func(a, *, b) -> str:
pass
class Func(Protocol):
def __call__(self, a, *, b) -> str: ...
def test(f: Func):
pass
test(func)  # ok!

Protocol用于结构类型化以定义输入类型,而不是用于继承。

您应该使用ABC而不是Protocol;它正是你想要的。