例如,我们有一个类:
class A:
def send(msg: bytes) -> None:
# implementation...
pass
def recv(n: int) -> bytes:
# implementation
pass
和一个功能:
def a(obj, n: int) -> None:
received = obj.recv(n)
obj.send(received)
很明显,不仅类A
的实例可以作为obj
参数传递,还可以传递socket.socket
的实例,可能是实现了recv
和send
的其他类。
一个注释/类型如何提示obj
参数,使其显示以下内容:
obj type must possess methods send and recv
send method must be of type Callable[[bytes], None]
recv method must be of type Callable[[int], bytes]
您真正需要的是通过打字进行鸭子打字(结构子类型)。协议以下是一些例子。
协议类的定义如下:
class Proto(Protocol): def meth(self) -> int: ...
此类主要用于识别结构子类型(静态鸭子类型)的静态类型检查器,例如:
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check
其中内置示例为
class typing.SupportsIndex
一个具有一个抽象方法CCD_ 8的ABC。
因此,对于您的情况,它可能类似于:
from typing import Protocol
class SupportsSendReceive(Protocol):
def send(self, msg: bytes) -> None:
...
def recv(self, n: int) -> bytes:
...
def a(obj: SupportsSendReceive, n: int) -> None:
received = obj.recv(n)
obj.send(received)
- 注意省略号
...
并不意味着你必须将代码代入其中。它确实应该是这样的。或者,如果3个点有问题,你也可以将pass
放入其中:)