Python 如何为Mypy类型批注指定OrderedDict K、V类型?
我正在使用Python3.5和Mypy对脚本进行一些基本的静态检查。最近,我重构了一些方法以返回OrderedDict,但在尝试使用指定键和值类型的返回注释时,遇到了“'type'对象不可订阅”错误 简化示例:Python 如何为Mypy类型批注指定OrderedDict K、V类型?,python,python-3.5,typing,mypy,Python,Python 3.5,Typing,Mypy,我正在使用Python3.5和Mypy对脚本进行一些基本的静态检查。最近,我重构了一些方法以返回OrderedDict,但在尝试使用指定键和值类型的返回注释时,遇到了“'type'对象不可订阅”错误 简化示例: #!/usr/bin/env python3.5 from collections import OrderedDict # this works def foo() -> OrderedDict: result = OrderedDict() # type: Orde
#!/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
回溯(最近一次呼叫最后一次):
文件“/foo.py”,第12行,在
def foo2()->OrderedDict[str,int]:
TypeError:“type”对象不可下标
然而,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”对象不可订阅
有趣的是,Python解释器在函数签名中看到下标的OrderedDict
时死亡,但很高兴在变量类型注释中接受它
无论如何,我的解决方法是在函数签名中使用Dict
而不是orderedict
(并添加一条注释,如果Python解释器将学会接受正确的签名,则应该修复此问题)。您还可以尝试使用可变映射
(如下面的回答:)
作为一种解决方法,您还可以将返回类型放入字符串中,以满足Mypy和Python 3.6的要求:
from collections import OrderedDict
def foo() -> 'OrderedDict[str, int]':
result = OrderedDict()
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
享受所有的世界 它现在可以工作了(mypy版本0.501)。只需存放一个指向修复程序的链接:是的,最后,我在自己的代码中使用了相同的解决方法。这在mypy 0.063中导致了一个错误,但建议将函数签名更改为字符串的答案是有效的。Pythontyping.OrderedDict
在3.7.2中引入的typing.OrderedDict
在3.9中再次被弃用,这增加了对collections.OrderedDict的支持[K,V]
。另一个解决方法是引用函数签名中的类型,例如,“OrderedDict[…]”
对于3.7,我尝试了建议:OrderedDict[str,Any]=OrderedDict()
但是在OrderedDict()下有一个红色的曲线
说泛型应该通过方括号指定。但是简单地用[]替换()也不能解决这个问题,因为现在它需要在[]中有一个表达式。我不确定我是否理解这个问题。@U noob请准确地编写给出错误的代码。另外,您是否使用3.7.5+?我实际上使用的是3.8.7。是的,因此我使用Pycharm,它建议使用[]
fix。我点击它让它修复,但现在它需要一个表达式。不确定我是否应该初始化一个没有类似建议的值:orderedict[str,Any]=orderedict[dummykey]
我甚至尝试了建议:orderedict[str,Any]={}
但随后linter警告说它需要OrderedDict,但得到了Dict。请尝试建议:OrderedDict[str,Any]=OrderedDict()
和建议[dummykey]=1
from collections import OrderedDict
import typing
def foo() -> typing.OrderedDict[str, int]:
result: typing.OrderedDict[str, int] = OrderedDict()
result['two'] = 2
return result