В Python IDLE допускается неправильный отступ?

Глядя на ответ, данный Второй Мировой Войной, я прокомментировал его отступ, сказав, что это неправильно. Однако, запустив его код в моем IDLE, я обнаружил, что он работает без проблем.

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

>>> def foo():
    return 0

>>> foo()
0
>>> def bar():
    return foo() + 5

>>> bar()
5
>>> def foobar():
    return foo() + bar()

>>> foobar()
5
>>> 

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

Почему такой вид отступа допускается в интерактивной IDLE, но не в обычных сценариях? Я просмотрел документацию по IDLE, а точнее раздел 25.5.2.1 "Автоматический отступ", который не помог найти ответ.

Кроме того, в документации Python о функциях говорится, что тела функций должны иметь отступ:

Ключевое слово def вводит определение функции. За ним должно следовать имя функции и заключенный в скобки список формальных параметров. Операторы, которые формируют тело функции, начинаются со следующей строки и должны иметь отступ.

(акцент мой)

Почему такого рода отступы разрешены в IDLE, но полностью отключены в обычном сценарии? Это специально? И если да, документировано ли это поведение где-нибудь?

3 ответа

Решение

>>> что вы видите в IDLE, это просто подсказка. Это чистое совпадение, что длина этого приглашения составляет четыре символа, и в вашем коде тоже есть отступ с четырьмя пробелами.

Чтобы увидеть и подумать о том, как на самом деле работает код, давайте удалим все >>> подсказки. Для ясности мы также удалим распечатанные результаты.

Теперь это выглядит как совершенно нормальный код Python:

def foo():
    return 0

foo()

def bar():
    return foo() + 5

bar()

def foobar():
    return foo() + bar()

foobar()

Так что IDLE ничем не отличается от любого другого интерпретатора Python, это просто способ >>> подскажите только в первой строке, что сбивает с толку. Если вы подумаете о том, как будет выглядеть код с удаленными четырьмя символами, это будет иметь больше смысла.

Код правильный, но IDLE REPL не похож на Python:

>>> def foo():
    return 0

IDLE печатает это, тогда как Python:

>>> def foo():
...     return 0

Обратите внимание, что четыре пробела перед возвратом есть, но поскольку они выровнены по крайнему левому столбцу, а не с префиксом с тремя точками и пробелом, пробелы, по-видимому, не существуют, если вы ожидали, что код будет иметь больше отступов.

У вас правильный отступ в IDLE и неверный в вашем скрипте.

В холостом ходу есть 4 пробела return 0, И в вашем сценарии нет.

Ваш скрипт должен выглядеть так:

def foo():
    return 0

def bar():
    return foo() + 5

def foobar():
    return foo() + bar()

print(foo())
print(bar())
print(foobar())

Ответ на вопрос "Почему верный отступ IDLE?"

Он использует >>> пометить как начало ввода следующей команды. Это стандартный метод. Он (в вариациях) используется повсеместно.

>>> <-start of the line. Zero spaces.
<-start of the line. Zero spaces.

Поэтому следующий код будет иметь неправильный отступ:

>>> def foo():
return 0

Потому что это эквивалент следующего кода, записанного в файле скрипта:

def foo():
return 0

Но

>>> <-start of the line. Zero spaces.
    <-start of the block. Indent 4 spaces.

Поэтому следующий код будет иметь правильный отступ:

>>> def foo():
    return 0

Потому что это эквивалент следующего кода, записанного в файле скрипта:

def foo():
    return 0
Другие вопросы по тегам