Почему это не синтаксическая ошибка в Python?
Сегодня обратил внимание на строку в нашей кодовой базе, которая, как я думал, наверняка провалила бы сборку с синтаксической ошибкой, но тесты проходили так, что, очевидно, это был действительно правильный python (как в 2.x, так и в 3).
Пробел иногда не требуется в условном выражении:
>>> 1if True else 0
1
Это не работает, если LHS является переменной:
>>> x = 1
>>> xif True else 0
File "<stdin>", line 1
xif True else 0
^
SyntaxError: invalid syntax
Но он все еще работает с другими типами литералов:
>>> {'hello'}if False else 'potato'
'potato'
Что здесь происходит, это преднамеренно является частью грамматики по какой-то причине? Является ли эта странная причуда известным / задокументированным поведением?
3 ответа
Пробел между токенами
За исключением начала логической строки или строковых литералов пространство пробельных символов, табуляция и подача форм могут использоваться взаимозаменяемо для разделения токенов. Пробел необходим между двумя токенами только в том случае, если их объединение могло бы быть интерпретировано как другой токен (например, ab - один токен, но ab - два токена).
Так что в этом случае 1if
не является допустимым токеном, поэтому пробел необязателен. 1
интерпретируется как целочисленный литерал, из которого if
не является частью Так if
интерпретируется отдельно и распознается как ключевое слово.
В xif
однако идентификатор распознается, поэтому Python не может увидеть, что вы хотели сделать x if
там.
Лексер Python генерирует два токена для ввода 1if
: целое число 1
и ключевое слово if
, поскольку токен, начинающийся с цифры, не может содержать строку if
, xif
с другой стороны, признается действительным идентификатором; нет никаких оснований полагать, что это идентификатор, за которым следует ключевое слово, и поэтому он передается анализатору как один токен.
С моим ограниченным знанием лексической обработки и токенизации я бы сказал, что вы видите, что любая часть, которую можно лексически анализировать как "отличную" (то есть числа / словари и т. Д.) От if
делается так. Большинство языков игнорируют пробелы, и я предполагаю, что Python делает то же самое (исключая, конечно, уровни отступов). Как только токены сгенерированы, самой грамматике все равно, она, скорее всего, ищет [EXPRESSION] [IF] [EXPRESSION] [ELSE] [EXPRESSION]
группировка, которая, опять же с вашими примерами, будет работать нормально.