考虑以下代码:
from typing import Callable, TypeVar
T = TypeVar('T')
def middle_man(
producer: Callable[[], T],
consumer: Callable[[T], None]
) -> None:
consumer(producer())
middle_man(
lambda: "HELLO",
lambda s: print(s.lower())
)
Run Code Online (Sandbox Code Playgroud)
这段代码可以正常运行,并且可以正常运行,但是,mypy无法推断s第二个lambda 的类型,从而出现错误:
“对象”没有属性“较低”
现在,我唯一的解决方法是强制转换s(可能是更复杂的lambda或类型更复杂的痛苦),或者添加# type: ignore(我宁愿不这样做)。
有更好的解决方法,还是让mypy识别类型的正确方法?
在我看来,您在这里有两个相互矛盾的担忧:
T TypeVar是通用的,以便producer和consumer参数的类型注释middle_man可以灵活middle_man足够具体,以便mypy识别您正在使用str类型调用它为了实现这一目标,我将middle_man首先将参数存储为变量来注释特定调用的参数:
from typing import Callable, TypeVar
T = TypeVar('T')
def middle_man(
producer: Callable[[], T],
consumer: Callable[[T], None]
) -> None:
consumer(producer())
producer: Callable[[], str] = lambda: "HELLO"
consumer: Callable[[str], None] = lambda s: print(s.lower())
middle_man(producer, consumer)
Run Code Online (Sandbox Code Playgroud)
编辑
另一个建议:
由于您无论如何都使用泛型TypeVar,因此您可以将其替换为Any类型,而不会丢失类型信息,并且mypy不会引发错误,因为它会跳过types的静态类型检查Any。
from typing import Callable, Any
def middle_man(
producer: Callable[[], Any],
consumer: Callable[[Any], None]
) -> None:
consumer(producer())
middle_man(
lambda: "HELLO",
lambda s: print(s.lower())
)
Run Code Online (Sandbox Code Playgroud)
我知道这个解决方案不是很令人满意,因为它本质上违背了用于静态类型检查的目的mypy,但除非您想将您的上限限制TypeVar为带有方法的类lower,否则这可能是您的最佳选择。
| 归档时间: |
|
| 查看次数: |
170 次 |
| 最近记录: |