Python:“有方法”的类型提示

win*_*win 8 python types annotations type-hinting python-typing

例如我们有一个类:

class A:
    def send(msg: bytes) -> None:
        # implementation...
        pass
    
    def recv(n: int) -> bytes:
        # implementation
        pass
Run Code Online (Sandbox Code Playgroud)

和一个函数:

def a(obj, n: int) -> None:
    received = obj.recv(n)
    obj.send(received)
Run Code Online (Sandbox Code Playgroud)

很明显,不仅类的实例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]
Run Code Online (Sandbox Code Playgroud)

Nie*_*ano 8

您真正需要的是通过typing.Protocol进行鸭子类型(结构子类型)。此列表中有一些示例。

协议类定义如下:

class Proto(Protocol):
    def meth(self) -> int:
        ...
Run Code Online (Sandbox Code Playgroud)

此类主要与识别结构子类型(静态鸭子类型)的静态类型检查器一起使用,例如:

class Proto(Protocol):
    def meth(self) -> int:
        ...
Run Code Online (Sandbox Code Playgroud)

内置示例在哪里

class typing.SupportsIndex

具有一个抽象方法的 ABC __index__

所以对于你的情况,它可能是这样的:

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)
Run Code Online (Sandbox Code Playgroud)
  • 请注意,省略号 ...并不意味着您必须将代码替换为其中。确实应该如此。pass或者如果这 3 个点令人烦恼,你也可以把它放在那里:)