假设我有以下内容:
from collections import OrderedDict
from dataclasses import dataclass
@dataclass
class HelloWorld:
x: OrderedDict[str, int]
a = OrderedDict([("a", 0), ("c", 2), ("b", 1)])
HelloWorld(a) <--- # type error here
产生的类型错误是:
Argument of type "OrderedDict[Literal['a', 'c', 'b'], Literal[0, 2, 1]]" cannot be assigned to parameter "x" of type "OrderedDict[str, int]" in function "__init__"
"OrderedDict[Literal['a', 'c', 'b'], Literal[0, 2, 1]]" is incompatible with "OrderedDict[str, int]"
Type parameter "_KT@OrderedDict" is invariant, but "Literal['a', 'c', 'b']" is not the same as "str"
Type parameter "_VT@OrderedDict" is invariant, but "Literal[0, 2, 1]" is not the same as "int
奇怪的是,这个非常相似的代码片段不会产生错误:
from collections import OrderedDict
from dataclasses import dataclass
@dataclass
class HelloWorld:
x: OrderedDict[str, int]
HelloWorld(OrderedDict([("a", 0), ("c", 2), ("b", 1)])) # <--- no error
cast
通常是一个可行的解决方案,但在这里您只需注释初始变量即可。这将保留代码的类型安全性(与cast
可以同样好地强制转换str
为不同dict[int, int]
)。Pyright 不应该抱怨以下内容:这里有一个游乐场。
这个错误是由于对 和不变性 (如同)
pyright
一起的过于乐观的推断引起的。OrderedDict
MutableMapping
正如 @InSync 在评论中注意到的那样,在 Python 3.7 及更高版本中,您可以从 dict 文字构建 OrderedDict 并仍然保留顺序,并且在这种情况下推理不太具体:
使用
typing.cast
: