簡體   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