it-swarm.com.ru

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

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

52
wim

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

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

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

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

63
poke

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

4
chepner

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

3
Brandon Buck