Python 3.x 使用TypeVar在MyPy中使用参数键入Decorator将生成预期的未占用类型
MyPy在Python 3.x 使用TypeVar在MyPy中使用参数键入Decorator将生成预期的未占用类型,python-3.x,decorator,python-decorators,mypy,Python 3.x,Decorator,Python Decorators,Mypy,MyPy在可调用*args和**kwargs方面存在一些问题,特别是在装饰器方面,详见: 具体来说,对于没有参数的装饰器,它只包装函数(并且不更改其签名),您需要以下内容: from typing import Any, Callable, cast, TypeVar FuncT = TypeVar('FuncT', bound=Callable[..., Any]) def print_on_call(func: FuncT) -> FuncT: def wrapped(*a
可调用
*args
和**kwargs
方面存在一些问题,特别是在装饰器方面,详见:
具体来说,对于没有参数的装饰器,它只包装函数(并且不更改其签名),您需要以下内容:
from typing import Any, Callable, cast, TypeVar
FuncT = TypeVar('FuncT', bound=Callable[..., Any])
def print_on_call(func: FuncT) -> FuncT:
def wrapped(*args, **kwargs):
print("Running", func.__name__)
return func(*args, **kwargs)
return cast(FuncT, wrapped)
结尾处的cast()
应该是不必要的(MyPy应该能够通过调用wrapped
结尾处的func
来推导出,wrapped确实是FuncT->FuncT
)。我可以忍受,直到它被修复
然而,当您引入带有参数的装饰器时,这种情况会非常糟糕。考虑装修师:
def print_on_call(foo):
def decorator(func):
def wrapped(*args, **kwargs):
print("Running", foo)
return func(*args, **kwargs)
return wrapped
return decorator
其用途如下:
@print_on_call('bar')
def stuff(a, b):
return a + b
我们可以尝试这样键入它(使用Guido认可的无参数示例作为指南):
这看起来像是打字检查,但当我们使用它时:
@print_on_call('bar')
def stuff(a: int, b: int) -> int:
return a + b
我们遇到了一个严重的错误:
error: Argument 1 has incompatible type Callable[[int, int], int]; expected <uninhabited>
然而,这仍然会导致上述错误。这将是我可以接受的,只要#type:ignore
ing离开,但不幸的是,由于这个问题,任何用这个装饰器装饰的函数都有类型
,所以你开始到处失去类型安全性
所有人都说了(tl;dr):
如何使用参数键入decorators(不修改函数的签名)?以上是一个错误吗?这能解决吗
MyPy版本:0.501(最新发布日期)Oops!看来我搜索得不够努力。这方面已经存在一个问题和解决方法:现在,mypy直接支持这一点: i、 e
FuncT=TypeVar(“FuncT”,bound=Callable[…,Any])
def my_decorator(func:func)->func:
@包装(func)
def wrapped(*args:Any,**kwargs:Any)->Any:
打印(“某物”)
返回函数(*args,**kwargs)
返回强制转换(函数,已包装)
TypeVar(F,…,耶)
error: Argument 1 has incompatible type Callable[[int, int], int]; expected <uninhabited>
from typing import Any, Callable, Dict, List, TypeVar
FuncT = TypeVar('FuncT', bound=Callable[..., Any])
def print_on_call(foo: str) -> Callable[[FuncT], FuncT]:
return cast(Callable[[FuncT], FuncT], None)