Я использую Python 3.6.1 и наткнулся на кое-что очень странное. У меня была простая опечатка в задании словаря, которую я долго искал.
context = {}
context["a"]: 2
print(context)
Вывод
{}
Что context["a"]: 2
делает код ? Он не поднимает, SyntaxError
когда должен, ИМО. Сначала я подумал, что это создает срез. Однако при вводе repr(context["a"]: 2)
файла SyntaxError
. Я также набрал context["a"]: 2
в консоли, и консоль ничего не печатала. Думал, может, вернулось None
, но не уверен.
Я также подумал, что это может быть однострочный оператор if, но это тоже не должен быть правильным синтаксисом.
Кроме того, context["a"]
следует поднять файл KeyError
.
Я в недоумении. Что происходит?
python
python-3.x
Джастенгель
источник
источник
Ответы:
Вы случайно написали синтаксически правильную аннотацию переменной . Эта функция была представлена в Python 3.6 (см. PEP 526 ).
Хотя аннотация переменной анализируется как часть аннотированного присваивания , оператор присваивания является необязательным :
Таким образом, в
context["a"]: 2
context["a"]
цель аннотации2
сама аннотацияcontext["a"]
остается неинициализированнымВ PEP указано, что «целью аннотации может быть любая допустимая единственная цель назначения, по крайней мере, синтаксически (что с этим делать - зависит от проверяющего типа)» , что означает, что ключ не обязательно должен существовать, чтобы быть аннотированный (следовательно, нет
KeyError
). Вот пример из оригинального PEP:Обычно выражение аннотации должно оцениваться как тип Python - в конце концов, основное использование аннотаций - это подсказка типа, но она не применяется. Аннотацией может быть любое допустимое выражение Python, независимо от типа или значения результата.
Как видите, в настоящее время подсказки типов очень разрешительны и редко полезны, если только у вас нет средства проверки статического типа, такого как mypy .
источник
=
оператор присваивания? Ключ не существует. Мне это кажется неправильным.:
это оператор присваивания. Мы просто «назначаем» только аннотацию типа, а не ключ. Я сомневаюсь, что для этого есть какая-то причина, просто непреднамеренный побочный эффект добавления синтаксиса аннотации.x: str
и сразу за нейtype(x)
, интерпретатор вызоветNameError
. IMO синтаксис должен обеспечивать, чтобы объект был предварительно определен или определен на месте. Это просто вносит путаницу.x = 'i am a string'
доx: str
делает последний вид излишним. Его вообще не следовало добавлять. Это было прекрасно в качестве комментария; Я никогда не показываю, что это использовалось так или иначе.