考虑以下代码:
&
此代码可以正常运行,并且可以正常运行,但是,mypy无法在第二个lambda中推断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())
)
的类型,从而给出了错误:
“对象”没有属性“下层”`
现在,我唯一的解决方法是强制转换s
(这可能会导致更复杂的lambda或类型更复杂的痛苦),或者添加s
(我宁愿这样做)不。
是否有更好的解决方法,或使mypy识别类型的正确方法?
答案 0 :(得分:1)
在我看来,您在这里有两个相互矛盾的问题:
T
TypeVar
通用,以便producer
的{{1}}和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)
,因此可以用TypeVar
类型替换它而不会丢失类型信息,并且Any
不会产生错误,因为它skips static type checking for Any
types
mypy
我知道此解决方案并不是很令人满意,因为它实质上无法达到使用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())
)
进行静态类型检查的目的,但是除非您想restrict the upper bound of your TypeVar
使用mypy
方法来创建类,否则这可能是您最好的选择。