我正在使用 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)。 但是,如果将
Dict
替换为
OrderedDict
,那么 mypy 仍然会很高兴,但执行它会因 TypeError: 'type' object is not subscriptable
而死。有趣的是,Python 解释器在函数签名中看到带下标的
OrderedDict
时就死掉了,但很乐意在变量类型注释中接受它。
无论如何,我的解决方法是在函数签名中使用
Dict
而不是
OrderedDict
(并添加一条注释,说明如果/当 Python 解释器学会接受正确的签名时,应该修复此问题)。from collections import OrderedDict
def foo() -> 'OrderedDict[str, int]':
result = OrderedDict()
result['foo'] = 123
return result
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())
from collections import OrderedDict
import typing
def foo() -> typing.OrderedDict[str, int]:
result: typing.OrderedDict[str, int] = OrderedDict()
result['two'] = 2
return result
享受所有世界!