[英]How do I specify OrderedDict K,V types for Mypy type annotation?
我正在使用 Python 3.5 和 Mypy 对我的脚本进行一些基本的静态检查。 最近我重构了一些返回 OrderedDict 的方法,但是当我尝试使用指定了 Key 和 Value 类型的返回注释时遇到了“'type' object is not subscriptable”错误。
简化示例:
#!/usr/bin/env python3.5
from collections import OrderedDict
# this works
def foo() -> OrderedDict:
result = OrderedDict() # type: OrderedDict[str, int]
result['foo'] = 123
return result
# this doesn't
def foo2() -> OrderedDict[str, int]:
result = OrderedDict() # type: OrderedDict[str, int]
result['foo'] = 123
return result
print(foo())
这是运行时的python输出:
Traceback (most recent call last):
File "./foo.py", line 12, in <module>
def foo2() -> OrderedDict[str, int]:
TypeError: 'type' object is not subscriptable
然而,Mypy 对注释中的类型注释没有问题,如果我尝试执行result[123] = 123
实际上会发出警告。
这是什么原因造成的?
mypy 中没有问题(至少,0.501 中没有)。 但有使用Python 3.6.0的一个问题。 考虑以下:
from collections import OrderedDict
from typing import Dict
def foo() -> Dict[str, int]:
result: OrderedDict[str, int] = OrderedDict()
result['two'] = 2
return result
此代码将同时满足 mypy (0.501) 和 Python (3.6.0)。 然而,如果你用OrderedDict
替换Dict
,那么 mypy 仍然会很高兴,但执行它会因为TypeError: 'type' object is not subscriptable
而死。
有趣的是,Python 解释器在函数签名中看到下标OrderedDict
时就死了,但很高兴在变量类型注释中接受它。
无论如何,我的解决方法是在函数签名中使用Dict
而不是OrderedDict
(并添加注释,如果/当 Python 解释器将学会接受正确的签名时,这应该被修复)。
作为一种解决方法,您还可以将返回类型放入字符串中以满足 Mypy 和 Python 3.6:
from collections import OrderedDict
def foo() -> 'OrderedDict[str, int]':
result = OrderedDict()
result['foo'] = 123
return result
您还可以尝试使用MutableMapping
(就像在这个答案中一样: https : MutableMapping
)
from collections import OrderedDict
from typing import Dict
def foo() -> MutableMapping[str, int]:
result = OrderedDict() # type: MutableMapping[str, int]
result['foo'] = 123
return result
我不知道哪个版本允许这样做,但是对于 2021 年 3 月/24 日,一个更好的解决方案,已针对 Python 3.7.5 进行了测试:
from collections import OrderedDict
import typing
def foo() -> typing.OrderedDict[str, int]:
result: typing.OrderedDict[str, int] = OrderedDict()
result['two'] = 2
return result
享受所有世界!
collections.OrderedDict 与 typing.OrderedDict 不同
from collections import OrderedDict as collections_OrderedDict
from typing import OrderedDict
# this works
def foo() -> OrderedDict[str, int]:
result = collections_OrderedDict()
result['foo'] = 123
return result
print(foo())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.