繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM