Zul*_*lan 11 python mypy python-typing
import unittest
from typing import *
T = TypeVar("T", bound=unittest.TestCase)
def decorate(func: Callable[[T], None]) -> Callable[[T], None]:
def decorated_function(self: T) -> None:
return func(self)
return decorated_function
Run Code Online (Sandbox Code Playgroud)
现在我什至有一个生成器来创建这些装饰器并想要速记这些装饰器。我对存储装饰器的变量使用什么类型(省略生成器的简化示例)。
my_decorate: Callable[[Callable[[T], None]], Callable[[T], None]] = decorate
Run Code Online (Sandbox Code Playgroud)
这可行,但很笨拙。所以问题是:
如何为该类型别名以避免编写完整签名?
不起作用的事情:
TD = Callable[[Callable[[T], None]], Callable[[T], None]]
my_decorate: TD[T] = decorator_variable
Run Code Online (Sandbox Code Playgroud)
给出错误
error: Type variable "mypytest.T" is unbound
note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
note: (Hint: Use "T" in function signature to bind "T" inside a function)
Run Code Online (Sandbox Code Playgroud)
相反,我可以用作TD[T]函数的参数类型。
仅使用my_decorate: TD = ...会产生--strict错误
error: Missing type parameters for generic type "TD"
Run Code Online (Sandbox Code Playgroud)
并且它不再检测错误的my_decorate.
在许多情况下,当Callable太有限时,请使用 aProtocol代替:
class TD(Protocol):
"""Type of any callable `(T -> None) -> (T -> None)` for all `T`"""
def __call__(self, __original: Callable[[T], None]) -> Callable[[T], None]:
...
Run Code Online (Sandbox Code Playgroud)
TD不是泛型类型,因此不需要“填充”类型变量。可以直接作为注解使用:
my_decorate: TD = decorate
Run Code Online (Sandbox Code Playgroud)
值得注意的是,TD.__call__尽管不是通用的,但仍然TD是通用的可调用对象。它T根据需要由每个调用的上下文填充。
| 归档时间: |
|
| 查看次数: |
542 次 |
| 最近记录: |