如何避免装饰函数的类型暗示丢失



我注意到,当包装具有某种类型提示的函数或方法时,当我使用Visual studio代码进行编码时,包装的方法会丢失类型提示信息。

例如,使用此代码:

from typing import Callable
import functools
def decorate(function: Callable):
@functools.wraps(function)
def wrapper(object: "A", *args, **kwargs):
return function(object, *args, **kwargs)
return wrapper
class A:
@decorate
def g(self, count: int) -> str:
return f"hello {count}"
a = A()
print(a.g(2))

当我在visualstudio代码中悬停在名称g上时,我会丢失类型提示信息。你知道防止这种情况发生的方法吗?

真诚的

使用Python 3.8(和3.9(可以做的最好的事情如下:

from __future__ import annotations
from functools import wraps
from typing import Any, Callable, TypeVar

T = TypeVar("T")

def decorate(function: Callable[..., T]) -> Callable[..., T]:
@wraps(function)
def wrapper(obj: A, *args: Any, **kwargs: Any) -> T:
return function(obj, *args, **kwargs)
return wrapper

class A:
@decorate
def g(self, count: int) -> str:
return f"hello {count}"

这将保留返回类型信息,但不保留有关参数类型的详细信息。@wraps装饰器至少应该保持签名的完整性。如果decorator被认为是A方法的通用,那么这就和它得到IMO.一样好

如果您希望它更具体,您可以始终将函数类型限制为Callable[[A, B, C], T],但装饰器将不再具有通用性。


如果升级到Python 3.10,您将可以访问ParamSpec。然后您可以执行以下操作:

from __future__ import annotations
from functools import wraps
from typing import Callable, ParamSpec, TypeVar

P = ParamSpec("P")
T = TypeVar("T")

def decorate(function: Callable[P, T]) -> Callable[P, T]:
@wraps(function)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
return function(*args, **kwargs)
return wrapper

class A:
@decorate
def g(self, count: int) -> str:
return f"hello {count}"

这实际上保留了(顾名思义(所有参数规范。

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新