foo.py
:
kwargs = {"a": 1, "b": "c"}
def consume(*, a: int, b: str) -> None:
pass
consume(**kwargs)
mypy foo.py
:
error: Argument 1 to "consume" has incompatible type "**Dict[str, object]"; expected "int"
error: Argument 1 to "consume" has incompatible type "**Dict[str, object]"; expected "str"
这是因为object
是int
和str
的超类型,因此可以推断。如果我声明:
from typing import TypedDict
class KWArgs(TypedDict):
a: int
b: str
然后将kwargs
注释为KWArgs
,mypy
检查通过。这实现了类型安全,但需要我在KWArgs
中复制consume
的关键字参数名称和类型。有没有一种方法可以在类型检查时从函数签名生成这个TypedDict
,这样我就可以最小化维护中的重复
据我所知,在这方面没有直接的解决办法,但有另一种优雅的方法来实现这一点:
我们可以利用
typing
sNamedTuple
创建一个包含参数的对象:现在,我们定义
consume
方法以接受它作为参数:整个守则是:
运行mypy将产生:
它将认识到
a
和b
是参数,并批准这一点运行代码将输出:
但是,如果我们将
b
更改为非字符串,mypy将抱怨:这样,我们通过定义一次方法的参数和类型来实现方法的类型检查
[1]因为如果基于另一个定义
TypedDict
或函数签名,则需要知道另一个的__annotations__
,这在检查时是未知的,而定义一个在运行时强制转换类型的修饰符将错过类型检查的点。相关问题 更多 >
编程相关推荐