繁体   English   中英

我可以使用 typing.Callable 类型来自动注释 function 吗? 如何?

[英]Can I use a typing.Callable type to annotate a function automatically? How?

假设我们像这样为回调定义一个类型:

CallbackFn = Callable[[str, str, int, int], None]

当我想实现回调 function 并让外部工具根据CallbackFn对其进行类型检查时,我必须显式注释类型:

def my_callback(s1: str, s2: str, i1: int, i2: int) -> None:
  ...

有什么方法可以使用CallbackFn中定义的类型提示来注释 function - 类似于def my_callback(s1,s2,i1,i2) as CallbackFn: - 以避免显式注释工作?

在少数情况下,是的。 但不推荐

my_callback: CallbackFn = lambda s1, s2, i1, i2: <do the thing>

显然你受到lambda的限制(没有声明等)

使用空操作装饰器很容易做到这一点。

from collections.abc import Callable
from typing import Any, TypeAlias, TypeVar

CallbackFn: TypeAlias = Callable[[str, str, int, int], None]
Any4ParamCallableT = TypeVar("Any4ParamCallableT", bound=Callable[[Any, Any, Any, Any], None])

def asCallbackFn(f: Any4ParamCallableT, /) -> CallbackFn:
    """No-op decorator to impart typing to the function being decorated"""
    return f

@asCallbackFn
def my_callback(s1, s2, i1, i2):
    return

这是故意在返回值和参数值中使用错误类型的尝试:

# mypy: Incompatible types in assignment (expression has type "None", variable has type "int") [assignment]
# mypy: Argument 1 to "my_callback" has incompatible type "int"; expected "str" [arg-type]
# mypy: Argument 2 to "my_callback" has incompatible type "int"; expected "str" [arg-type]
retval: int = my_callback(1, 2, 3, 4)

我真的不建议尝试做你正在做的事情,最好明确地键入每个 function。除此之外,如果你使用Callable[[<type>, ...], ...]内容,你将失去使用关键字参数调用约定的能力Callable[[<type>, ...], ...] (您可以使用回调协议,但这会强制您使用相同的命名参数命名所有回调函数)。

你可以使用装饰器来做到这一点

装饰师 function:

def annotate(callback):

    def wrapper(fn):
        print(fn)
        
        annotations = callback.__dict__["__args__"]

        for i, name in enumerate(fn.__code__.co_varnames):
            fn.__annotations__[name] = annotations[i]

        fn.__annotations__['return'] = annotations[-1]
        
        return fn

    return wrapper

要使用它,只需执行以下操作:

CallbackFn = Callable[[str, str, int, int], None]

@annotate(CallbackFn)
def my_callback(s1: str, s2: str, i1: int, i2: int) -> None:
  pass

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM