繁体   English   中英

当装饰器更改通用返回类型时键入 function

[英]Typing function when decorator change generic return type

这类似于装饰器更改返回类型时输入 function但这次使用通用返回类型

from typing import Generic, TypeVar, Generic, Callable, Any, cast

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, item: T):
        self.item: T = item

def my_decorator(f: Callable[..., T]) -> Callable[..., Container[T]]:

    def wrapper(*args: Any, **kwargs: Any) -> Container[T]:
        return Container(f(*args, **kwargs))

    return cast(Callable[..., Container[T]], wrapper)

@my_decorator
def my_func(i: int, s: str) -> bool: ...

reveal_type(my_func) # Revealed type is 'def (*Any, **Any) -> file.Container[builtins.bool*]

需要哪个 mypy 魔法来保持my_func参数类型完整?

使用typing.Protocol看起来很有希望,但我不知道如何让它工作。

使用Callable[..., T]目前是最好的注解方法。

PEP 612 引入了ParamSpec ,它可以像TypeVar使用,并将解决您的问题。 目前计划用于 Python 3.10,并将使用typing_extensions支持旧版本

在那里你会写:

T = TypeVar('T')
P = ParamSpec('P')

def my_decorator(f: Callable[P, T]) -> Callable[P, Container[T]]:

    def wrapper(*args: Any, **kwargs: Any) -> Container[T]:
        return Container(f(*args, **kwargs))

    return cast(Callable[P, Container[T]], wrapper)

mypy 对 PEP 612 的支持尚未完成: https://github.com/python/mypy/issues/8645 与 pytype(Google 的 python 类型检查器)相同。

pyright(Microsoft 的 python typechecker)和 pyre(facebook 的 python typechecker)已经支持 PEP 612

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM