2016-12-18 15 views
7

Używam Python 3.5 wraz z Mypy, aby mieć pewne podstawowe sprawdzanie statyczne dla mojego skryptu. Ostatnio refaktoryzowałem niektóre metody zwracania OrderedDict, ale wpadłem na "obiekt typu" nie jest indeksowany ", gdy próbowałem użyć adnotacji zwracanej z podanymi kluczami i wartościami.Jak określić typy OrderedDict K, V dla adnotacji typu Mypy?

Zmniejszona przykład:

#!/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()) 

I to jest wyjście pyton gdy jest prowadzony:

Traceback (most recent call last): 
    File "./foo.py", line 12, in <module> 
    def foo2() -> OrderedDict[str, int]: 
TypeError: 'type' object is not subscriptable 

Mypy ma jednak żadnego problemu z adnotacją typu w komentarzu i będzie w rzeczywistości ostrzec jeśli próbuję zrobić result[123] = 123.

Co to powoduje?

+1

Działa teraz (mypy wersja 0,501). – max

Odpowiedz

5

Nie ma problemu z mypy (przynajmniej nie w 0.501). Ale istnieje jest Problem z Python 3.6.0. Rozważmy następujący:

from collections import OrderedDict 
from typing import Dict 

def foo() -> Dict[str, int]: 
    result: OrderedDict[str, int] = OrderedDict() 
    result['two'] = 2 
    return result 

Kod ten będzie zarówno zaspokoić mypy (0,501) i Pythona (3.6.0). Jeśli jednak zamienisz Dict na OrderedDict, to nadal będzie szczęśliwy, ale wykonanie go umrze z TypeError: 'type' object is not subscriptable.

Interesujące jest to, że interpreter Pythona umiera po wyświetleniu subskrybowanego OrderedDict w sygnaturze funkcji, ale z przyjemnością przyjmuje je w adnotacji typu zmiennej.

W każdym razie, moim obejściem tego problemu jest użycie Dict zamiast OrderedDict w sygnaturze funkcji (i dodać komentarz, że należy to naprawić, jeśli/kiedy interpreter Pythona nauczy się akceptować poprawny podpis).

+1

Tak, skończyłem używając tego samego obejścia w moim własnym kodzie. – Xarn

1

Co można także spróbować korzysta MutableMapping (jak w tej odpowiedzi: 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 
Powiązane problemy