Ćwiczę używanie podpowiedzi typu w Pythonie 3.5. Jeden z moich kolegów używa typing.Dict
:
import typing
def change_bandwidths(new_bandwidths: typing.Dict,
user_id: int,
user_name: str) -> bool:
print(new_bandwidths, user_id, user_name)
return False
def my_change_bandwidths(new_bandwidths: dict,
user_id: int,
user_name: str) ->bool:
print(new_bandwidths, user_id, user_name)
return True
def main():
my_id, my_name = 23, "Tiras"
simple_dict = {"Hello": "Moon"}
change_bandwidths(simple_dict, my_id, my_name)
new_dict = {"new": "energy source"}
my_change_bandwidths(new_dict, my_id, my_name)
if __name__ == "__main__":
main()
Oba działają dobrze, wydaje się, że nie ma różnicy.
Zapoznałem się z typing
dokumentacją modułu .
Pomiędzy typing.Dict
lub dict
którego powinienem używać w programie?
def a(b: int) -> bool:
to błąd składniowy w Pythonie 2.7 i myślę, że jest to również błąd składniowy w starszych wersjach Pythona 3.Odpowiedzi:
Nie ma prawdziwej różnicy między używaniem zwykłego
typing.Dict
adict
nie.Jednak
typing.Dict
jest to typ rodzajowy * , który pozwala określić typ kluczy i wartości zbyt , dzięki czemu jest bardziej elastyczny:def change_bandwidths(new_bandwidths: typing.Dict[str, str], user_id: int, user_name: str) -> bool:
W związku z tym może się zdarzyć, że w pewnym momencie życia projektu zechcesz nieco dokładniej zdefiniować argument słownikowy, w którym to momencie rozszerzenie
typing.Dict
dotyping.Dict[key_type, value_type]
będzie „mniejszą” zmianą niż zastąpieniedict
.Możesz uczynić to jeszcze bardziej ogólnym, używając
Mapping
lubMutableMapping
typów tutaj; ponieważ twoja funkcja nie musi zmieniać mapowania, trzymałbym sięMapping
. Adict
to jedno mapowanie, ale możesz utworzyć inne obiekty, które również będą zgodne z interfejsem mapowania, a Twoja funkcja może nadal działać z tymi:def change_bandwidths(new_bandwidths: typing.Mapping[str, str], user_id: int, user_name: str) -> bool:
Teraz jesteś wyraźnie mówią inni użytkownicy tej funkcji, że kod nie będzie faktycznie zmieniają się
new_bandwidths
mapowanie przekazany w.Twoja rzeczywista implementacja po prostu oczekuje obiektu, który można wydrukować. Może to być implementacja testowa, ale w obecnym stanie kod nadal działałby, gdybyś był używany
new_bandwidths: typing.Any
, ponieważ każdy obiekt w Pythonie można wydrukować.* : Uwaga: jeśli korzystasz z Pythona 3.7 lub nowszego, możesz używać go
dict
jako typu ogólnego, jeśli uruchomisz swój moduł zfrom __future__ import annotations
, a od Pythona 3.9dict
(a także z innymi standardowymi kontenerami) obsługuje używanie jako typu ogólnego nawet bez tego dyrektywy .źródło
{"name": "bob", "age" : 51}
Czy byłoby to coś podobnegotyping.Mapping[Union[str, int]
? A co z zagnieżdżonym słownikiem{"person": {"name":"bob", "age": 51}
, który mógłby być podobnytyping.Mapping[str, typing.Mapping[Union[str, int]]
? Używanie wUnion
ten sposób jest dla mnie kłopotliwe, ponieważ nie jest to ścisły schemat, ponieważ nie ma porządku. Może to w porządku, czy jest alternatywa?Union
pytania, które widzę, to wciąż otwarta dyskusja github.com/python/typing/issues/28typing.Dict
jest ogólną wersjądict
:Tutaj możesz określić typ klucza i wartości w dict:
Dict[str, int]
źródło