簡體   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