在下面的示例中,为什么将变量foo
的类型设置为整数但变量bar["foo"]
的类型却没有改变?
import typing as tp
foo: tp.Union[float, int]
D = tp.TypedDict("D", {"foo": tp.Union[float, int]})
foo = 123.45
bar = D(foo=123.45)
reveal_type(foo) # main.py:9: note: Revealed type is 'builtins.float'
reveal_type(bar["foo"]) # main.py:10: note: Revealed type is 'builtins.float'
foo = int(foo)
bar["foo"] = int(bar["foo"])
reveal_type(foo) # main.py:15: note: Revealed type is 'builtins.int'
reveal_type(bar["foo"]) # main.py:16: note: Revealed type is 'builtins.float'
答案 0 :(得分:2)
这归因于某些mypy
功能:
Union
的类型。 初始声明后的任何赋值都会缩小类型
x: Union[int, float]
x = 1.1
reveal_type(x) # Revealed type is 'builtins.float'
但是mypy
不会缩小分配中的类型:
x: Union[int, float] = 1.1
reveal_type(x) # Revealed type is 'Union[builtins.int, builtins.float]'
promotion of types
的{{1}}。 例如,mypy
在运行时不是int
的子类型,但是float
认为是。尽管不是mypy
的子类型,但只要在float
处都可以传递int
(有时可能并不明显)。
Union
的类属性 class A:
x: Union[bool, int, float]
reveal_type(A.x) # Revealed type is 'builtins.float'
此结果是因为bool
是int
的子类型,并且int
将float
提升为mypy
。
在您的TypedDict
示例中,有一个Union
的简化形式,如下所示:
from typing import Union, TypedDict
D = TypedDict("D", {"x": Union[int, float]})
d: D
y: Union[int, float]
reveal_type(d["x"]) # Revealed type is 'builtins.float'
reveal_type(y) # Revealed type is 'Union[builtins.int, builtins.float]'