def timer(func: Callable[..., Any]) -> Callable[..., Any]:
"""Calculates the runtime of a function, and outputs it to logging.DEBUG."""
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
value = func(*args, **kwargs)
end = perf_counter()
_logger = logging.getLogger(__name__ + '.' + func.__name__)
_logger.debug(' runtime: {:.4f} seconds'.format(end - start))
return value
return wrapper
答案 0 :(得分:3)
此方法的问题在于,现在MyPy丢失了返回类型,或者简而言之,它退化为Any
,因此请考虑:
import logging
from typing import Callable, Any
from time import perf_counter
from functools import wraps
def timer(func: Callable[..., Any]) -> Callable[..., Any]:
"""Calculates the runtime of a function, and outputs it to logging.DEBUG."""
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
value = func(*args, **kwargs)
end = perf_counter()
_logger = logging.getLogger(__name__ + '.' + func.__name__)
_logger.debug(' runtime: {:.4f} seconds'.format(end - start))
return value
return wrapper
@timer
def func(x:int) -> int:
return x
def string_func(s: str):
return s[:]
x = 42 * func(42)
reveal_type(x)
string_func(x)
使用:
(py37) Juans-MacBook-Pro:tempdata juan$ mypy --version
mypy 0.641
如果我尝试对此进行类型检查,它会通过!
(py37) Juans-MacBook-Pro:tempdata juan$ mypy typing_decorators.py
typing_decorators.py:29: error: Revealed type is 'Any'
在您想精确保存参数的情况下,我找到了一种解决方案,即使用TypeVar
并使用cast
包装器MyPy可以确切知道类型(假设原始函数已添加注释):
import logging
from typing import Callable, Any, TypeVar, cast
from time import perf_counter
from functools import wraps
F = TypeVar('F', bound=Callable[..., Any])
def timer(func: F) -> F:
"""Calculates the runtime of a function, and outputs it to logging.DEBUG."""
@wraps(func)
def wrapper(*args, **kwargs):
start = perf_counter()
value = func(*args, **kwargs)
end = perf_counter()
_logger = logging.getLogger(__name__ + '.' + func.__name__)
_logger.debug(' runtime: {:.4f} seconds'.format(end - start))
return value
return cast(F, wrapper)
@timer
def func(x:int) -> int:
return x
def string_func(s: str):
return s[:]
x = 42 * func(42)
reveal_type(x)
string_func(x)
在这种情况下:
(py37) Juans-MacBook-Pro:tempdata juan$ mypy typing_decorators.py
typing_decorators.py:32: error: Revealed type is 'builtins.int'
typing_decorators.py:34: error: Argument 1 to "string_func" has incompatible type "int"; expected "str"
答案 1 :(得分:1)
缩进在这里似乎有点过头,但是否则,是的,类型并不正确。不过,您可以使此方法更加精确。您输出的函数与输入的函数具有相同的返回类型,但是您不必注意这一点。
特别是,您可以说类似
select discordid, RANK() OVER
(PARTITION BY u.userid ORDER BY (the column that you are ranking from) DESC) AS Rank from otherqueryresult as q inner join user as u on u.id=q.userid
似乎您应该能够对args / kwargs进行相同的操作,但是根据我自己的打字经验,我还没有遇到过这种情况,因此我无法确切地说出该怎么做。编辑-有关键入这些内容的更多信息,请参见this GitHub issue;似乎还不可能(是吗?)。
我想你也可以说
from typing import Callable, TypeVar
T = TypeVar("T")
def timer(func: Callable[..., T]) -> Callable[..., T]:
但这似乎没有用。