Подтвердить что ты не робот

Почему это не синтаксическая ошибка в 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'

Что происходит здесь, намеренно ли оно является частью грамматики по какой-то причине? Является ли эта странная причуда известным/документированным поведением?

4b9b3361

Ответ 1

Пробел между токенами

За исключением в начале логической строки или строковых литералов пробельные символы пробелов, вкладки и формы могут использоваться взаимозаменяемо для разделения токенов. Пробелы необходимы между двумя токенами, только если их конкатенация иначе интерпретируется как другой токен (например, ab - это один токен, а b - два токена).

Итак, в этом случае 1if не является допустимым токеном, поэтому пробел является необязательным. 1 интерпретируется как целочисленный литерал, из которого if не является частью. Таким образом, if интерпретируется отдельно и распознается как ключевое слово.

В xif однако идентификатор распознается, поэтому Python не может видеть, что вы хотели сделать там x if.

Ответ 2

Лексер Python генерирует два токена для ввода 1if: целое число 1 и ключевое слово if, так как ни один токен, начинающийся с цифры, не может содержать строку if. xif, с другой стороны, распознается как действительный идентификатор; нет оснований полагать, что это идентификатор, за которым следует ключевое слово, и поэтому передается парсеру как один токен.

Ответ 3

С моим ограниченным знанием лексической обработки и токенизации я бы сказал, что вы видите, что любая часть, которая может лексически анализироваться как "другая" (то есть числа/словари и т.д.) из if делаются так. Большинство языков игнорируют пробелы, и я полагаю, что Python делает то же самое (исключая, конечно, уровни отступов). Когда генерируются токены, сама грамматика не заботится, скорее всего, она ищет группу [EXPRESSION] [IF] [EXPRESSION] [ELSE] [EXPRESSION], которая, опять же с вашими примерами, будет работать нормально.