Почему это не синтаксическая ошибка в 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] группировка, которая, опять же с вашими примерами, будет работать нормально.

Другие вопросы по тегам