web-dev-qa-db-ja.com

Mypy型注釈にOrderedDict K、V型を指定するにはどうすればよいですか?

私はPython 3.5をMypyと一緒に使用して、スクリプトの基本的な静的チェックを行っています。最近、OrderedDictを返すようにいくつかのメソッドをリファクタリングしましたが、「 'type'オブジェクトは下付きではありません」というエラーが発生しました。キーと値のタイプを指定してreturnアノテーションを使用しようとしたとき。

削減された例:

#!/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を実行しようとすると警告が表示されます。

何が原因ですか?

24
Xarn

Mypyには問題はありません(少なくとも0.501では問題ありません)。しかし、そこにはis 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)の両方を満たします。ただし、DictOrderedDictに置き換えても、mypyは幸せですが、実行するとTypeError: 'type' object is not subscriptable

興味深いのは、Pythonインタープリターが関数のシグニチャーで下付きのOrderedDictを見ると死にますが、変数タイプの注釈でそれを受け入れて喜んでいることです。

とにかく、これに対する私の回避策は、関数のシグネチャでDictではなくOrderedDictを使用することです(Python通訳は正しい署名を受け入れることを学びます)。

20
Oren Ben-Kiki

回避策として、戻り値の型を文字列に入れて、MypyとPython 3.6の両方を満たすようにすることもできます。

from collections import OrderedDict

def foo() -> 'OrderedDict[str, int]':
    result = OrderedDict()
    result['foo'] = 123
    return result
11
Dion

また、MutableMappingを使用することもできます(この回答のように https://stackoverflow.com/a/44167921/138661

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
Arany