我有以下代码。类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
;它正是你想要的。