Python:为 "has method" 输入提示

Python: Type Hint for "has method"

比如我们有一个class:

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)

很明显,不仅 class A 的实例可以作为 obj 参数传递,而且 socket.socket 的实例,也许其他 classes,已实施 recvsend

一个 annotate/type 怎么能暗示 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]

您真正需要的是 duck-typing (structural subtyping) via typing.Protocol. Some examples are in this list

Protocol classes are defined like this:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing), for example:

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

An ABC with one abstract method __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)
  • 请注意 ellipsis ... 并不意味着您必须将代码替换到其中。它真的应该如何。或者你也可以把 pass 放在那里如果 3 个点很烦 :)