从另一个通用Lambda参数推论通用Lambda参数

时间:2019-07-26 16:48:41

标签: python mypy

考虑以下代码:

&

此代码可以正常运行,并且可以正常运行,但是,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识别类型的正确方法?

1 个答案:

答案 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方法来创建类,否则这可能是您最好的选择。