如何解决Mypy:dict值的类型不会随赋值而改变,而变量的类型却会随赋值而改变
在下面的示例中,为什么将变量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'
解决方法
这归因于某些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]'
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。