Почему отступы с явным продолжением строк не допускают комментариев в Python?

Я пишу парсер Python, чтобы узнать Flex и Bison, и я пытаюсь выяснить, почему только первая из этих программ является действительной Python.

a.py:

\
# This is valid Python

не вызывает ошибок.

b.py:

    \
# This is not valid Python

вызывает эту ошибку:

  File "b.py", line 1
    \
    ^
IndentationError: unexpected indent

и c.py:

if True:
    pass
    \
    # This is not valid Python

вызывает эту ошибку:

  File "c.py", line 4
    # This is not valid Python
                             ^
SyntaxError: invalid syntax

Я использую Python 2.6.5 (r265: 79063, 16 апреля 2010, 13:09:56) [GCC 4.4.3] на linux2 (Ubuntu 10.04); Тем не менее, тестирование на ideone.com предполагает, что поведение на Python 3 одинаково.

Ответ 1

Это деталь реализации.

Вот как несколько разных реализаций реагируют на ваш код:

                 a.py  b.py  c.py    
                 ----  ----  ----
CPython 2.6.5     ok    bad   bad
CPython 3.?       ok    bad   bad
Jython 2.2.1      ok    ok    bad
Jython 2.5.2      bad   bad   bad
IronPython 2.7.1  ok    bad   ok

Мое чтение раздела Exlplicit Line Joining в справочнике по языку Python заключается в том, что все три примера могут считаться действительными:

Две или несколько физических линий могут быть объединены в логические линии, используя символы обратной косой черты (\), а именно: когда физическая линия заканчивается на обратная косая черта, которая не является частью строкового литерала или комментария, соединенный со следующим образующим единую логическую линию, удаляя обратная косая черта и следующий символ конца строки.

Если CPython был изменен, чтобы принять все три примера как допустимые, я сомневаюсь, что его заметили бы его пользователи, изменили бы характер языка или нарушили бы любой код.

Ответ 2

Цитата Стивена актуальна, но она по-прежнему прямо не объясняет эту ситуацию.

Я думаю, что ключевое понимание состоит в том, что символ продолжения строки заставляет Python рассматривать линию как не просто пробел.

  • a.py: Кажется, он обрабатывает первую строку как пробел. Не это; как только символ продолжения линии достигнут, он и новая строка будут удалены, и поэтому, поскольку в этой строке нет ничего, что не существует для целей синтаксического анализа, у вас есть только одна строка с комментарием. Примечание: Jython 2.5.2 рассматривает это в основном так, как ожидалось; допустимый код Python ожидается на более поздней строке.

  • b.py: никогда не добавляется к комментарию, как только достигается символ продолжения линии, а строка больше не просто пробегает, отступ становится ошибкой.

  • c.py: комментарий снова не имеет значения, вы получите ту же ошибку с любым количеством пробелов и/или комментариями на следующей строке. Вы должны иметь реальный код Python в строке, следующей за символом продолжения строки.

Ответ 3

\ может присоединиться, EOL, EOF

Итак, это работает

\
# This is valid Python

но здесь

if True:
    \
    # This is not valid Python

после \ анализатор ищет строку с отступом, которая не существует.

Ответ 4

Гвидо регулярно напоминает в своем блоге и почтовых сообщениях, что он хочет как можно проще сохранить реализацию парсера Python.

Я не думаю, что это предполагаемое поведение, я думаю, что это побочный эффект наличия строгого и простого синтаксиса. Некоторые вещи просто не разрешены, и никто не заботился, чтобы проверить, были ли они, потому что это не имеет значения.