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