【发布时间】:2021-10-31 18:24:03
【问题描述】:
我正在尝试使用 MyPy 进行严格的类型检查,但我似乎无法让带有参数的装饰器在不引发冲突错误的情况下工作。
根据文档和其他答案,我认为你应该有这样的东西:
from time import sleep
from typing import TypeVar, Any, Callable, cast
F = TypeVar('F', bound=Callable[..., Any])
def multi_try_if_error(n_tries: int, sleep_duration: int) -> F:
def decorator(fn: F) -> F:
def wrapper(*args, **kwargs):
for _ in range(n_tries):
try:
return fn(*args, **kwargs)
except Exception as e:
caught = e
sleep(sleep_duration)
raise ValueError(caught)
return cast(F, wrapper)
return cast(F, decorator)
# example usage — this is where the error is raised
@multi_try_if_error(n_tries=3, sleep_duration=1)
def query_db(q: str) -> None:
return
但这会产生以下错误:
lib/decorator_defined.py:32: error: Function is missing a type annotation
lib/decorator_used.py:23: error: Untyped decorator makes function "query_db" untyped
lib/decorator_used.py:23: error: <nothing> not callable
即使这不是文档所建议的,我也可以将包装器定义更改为:
def wrapper(*args: Any, **kwargs: Any) -> Any:
for _ in range(n_tries):
...
这解决了第一个错误,但无论在哪里使用装饰器,我仍然有另外两个装饰器错误。
关于如何解决这个问题的任何想法?
这个错误可以在 Mypy Playgroundhere 上重现。
【问题讨论】:
-
@AlexWaygood 感谢您的回复!所以实际上不是装饰器定义的问题,而是装饰器与另一个函数的定义一起使用时。我已经编辑了我的问题以显示这一点(可以在操场上重现)。
-
@AlexWaygood
ReadDataError只是一个ValueError,可以相应地替换,没有区别。我还编辑了问题来解决这个问题。
标签: python python-decorators type-hinting mypy python-typing