Używam Pythona 3.6.1 i natknąłem się na coś bardzo dziwnego. Miałem prostą literówkę w przypisaniu do słownika, której znalezienie zajęło mi dużo czasu.
context = {}
context["a"]: 2
print(context)
Wynik
{}
Co context["a"]: 2
robi kod ? Nie zgłasza, SyntaxError
kiedy powinien IMO. Na początku myślałem, że tworzy kawałek. Jednak wpisywanie repr(context["a"]: 2)
podnosi SyntaxError
. Wpisałem też context["a"]: 2
w konsoli i konsola nic nie wydrukowała. Myślałem, że może wróciło None
, ale nie jestem tego taki pewien.
Pomyślałem również, że może to być pojedyncza linia instrukcji if, ale to też nie powinna być właściwa składnia.
Dodatkowo context["a"]
powinien podbić KeyError
.
Jestem zakłopotany. Co się dzieje?
python
python-3.x
justengel
źródło
źródło
Odpowiedzi:
Przypadkowo napisałeś poprawną składniowo adnotację do zmiennej . Ta funkcja została wprowadzona w Pythonie 3.6 (patrz PEP 526 ).
Chociaż adnotacja zmiennej jest analizowana jako część przypisania z adnotacjami , instrukcja przypisania jest opcjonalna :
Tak więc w
context["a"]: 2
context["a"]
jest celem adnotacji2
to sama adnotacjacontext["a"]
pozostaje niezainicjalizowanyPEP stwierdza, że „celem adnotacji może być dowolny ważny pojedynczy cel przypisania, przynajmniej pod względem składniowym (co z tym zrobić zależy od sprawdzania typu)” , co oznacza, że klucz nie musi istnieć, aby być opatrzone adnotacjami (stąd nie
KeyError
). Oto przykład z oryginalnego PEP:Zwykle wyrażenie adnotacji powinno być szacowane na typ Pythona - w końcu głównym zastosowaniem adnotacji jest podpowiedź do typu, ale nie jest ona wymuszana. Adnotacja może być dowolnym prawidłowym wyrażeniem Pythona, niezależnie od typu lub wartości wyniku.
Jak widać, w tej chwili podpowiedzi dotyczące typów są bardzo przyzwalające i rzadko przydatne, chyba że masz statyczne narzędzie do sprawdzania typów, takie jak mypy .
źródło
=
operatora przypisania? Klucz nie istnieje. Po prostu wydaje mi się to złe.:
jest operatorem przypisania. Po prostu „przypisujemy” samą adnotację typu, a nie klucz. Wątpię, czy jest jakikolwiek powód, by na to zezwolić, tylko niezamierzony efekt uboczny dodania składni adnotacji.x: str
i zaraz po niej nastąpitype(x)
, tłumacz podniesieNameError
. IMO składnia powinna wymuszać, że obiekt jest wstępnie zdefiniowany lub zdefiniowany na miejscu. To tylko wprowadza zamieszanie.x = 'i am a string'
wcześniejszegox: str
sprawia, że ten drugi rodzaj jest zbędny. W ogóle nie powinno być dodawane. To było w porządku jako komentarz; Nigdy nie pokazuję, że był używany w taki czy inny sposób.