有没有一种方法可以安全地判断派生协议的python类的类型?
如果我使用某个方法函数签名定义协议,则隐式子类必须定义具有兼容签名的方法:
# protocols.py
from abc import abstractmethod
from dataclasses import dataclass
from typing import Protocol
class SupportsPublish(Protocol):
@abstractmethod
def publish(self, topic: str):
...
def publish(m: SupportsPublish):
m.publish("topic")
@dataclass
class Publishable:
foo: str = "bar"
def publish(self):
print(self)
publish(Publishable())
# ✗ mypy protocols.py
# protocols.py:24: error: Argument 1 to "publish" has incompatible type "Publishable"; expected "SupportsPublish" [arg-type]
# protocols.py:24: note: Following member(s) of "Publishable" have conflicts:
# protocols.py:24: note: Expected:
# protocols.py:24: note: def publish(self, topic: str) -> Any
# protocols.py:24: note: Got:
# protocols.py:24: note: def publish(self) -> Any
# Found 1 error in 1 file (checked 1 source file)
但是,如果我显式地子类型SupportsPublish
,mypy不会报告类型错误:
...
@dataclass
class Publishable(SupportsPublish):
...
# ✗ mypy protocols.py
# Success: no issues found in 1 source file
基于来自PEP的this blurb,我预计类型判断器会发现函数签名不匹配:
请注意,显式和隐式子类型之间几乎没有区别,显式子类化的主要好处是"免费"获得一些协议方法.此外,类型判断器可以静态地验证类是否确实正确地实现了协议:
这就是我的环境:
> mypy --version
mypy 1.3.0 (compiled: yes)
> python --version
Python 3.9.17
我以为mypy会指出函数签名不匹配的问题.