如何为Mypy类型注释指定OrderedDict K,V类型?

问题描述 投票:0回答:5

我正在使用 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

这是什么原因造成的?

python python-typing mypy
5个回答
38
投票

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 解释器学会接受正确的签名时,应该修复此问题)。
    


17
投票

from collections import OrderedDict def foo() -> 'OrderedDict[str, int]': result = OrderedDict() result['foo'] = 123 return result



6
投票

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())



2
投票
MutableMapping

(就像这个答案:

https://stackoverflow.com/a/44167921/1386610
from collections import OrderedDict from typing import Dict def foo() -> MutableMapping[str, int]: result = OrderedDict() # type: MutableMapping[str, int] result['foo'] = 123 return result



2
投票

from collections import OrderedDict import typing def foo() -> typing.OrderedDict[str, int]: result: typing.OrderedDict[str, int] = OrderedDict() result['two'] = 2 return result

享受所有世界!

© www.soinside.com 2019 - 2024. All rights reserved.