Интерпретация Python табуляции и пробелов для отступа - PullRequest
32 голосов
/ 09 января 2010

Я решил, что немного изучу Python.В первом введении говорится, что для группировки операторов используется отступ.Хотя лучше всего использовать только один из них, что произойдет, если я их поменяю?Сколько пробелов будет считаться равным одной вкладке?Или он вообще не будет работать, если вкладки и пробелы будут смешаны?

Ответы [ 7 ]

35 голосов
/ 09 января 2010

Пробелы не рассматриваются как эквивалент табуляции. Строка с отступом табуляции отличается от строки с 1, 2, 4 или 8 пробелами.

Доказательство контрпримером ( ошибочно или, в лучшем случае, ограничено - табуляция! = 4 пробела ):

x = 1
if x == 1:
^Iprint "fff\n"
    print "yyy\n"

^I показывает TAB . При запуске через Python 2.5 я получаю сообщение об ошибке:

  File "xx.py", line 4
    print "yyy\n"
                ^
IndentationError: unindent does not match any outer indentation level

Таким образом, показывая, что в Python 2.5 вкладки не равны пробелам (и, в частности, не равны 4 пробелам).


Упс - неловко; мое доказательство контрпримером показывает, что вкладки не эквивалентны 4 пробелам. Как указывает Алекс Мартелли в комментарии , в Python 2 вкладки эквивалентны 8 пробелам, а адаптация примера с вкладкой и 8 пробелами показывает, что это действительно так.

x = 1
if x != 1:
^Iprint "x is not 1\n"
        print "y is unset\n"

В Python 2 этот код работает, ничего не печатая.


В Python 3 правила немного отличаются ( отметил от Антти Хаапала ). Сравните:

Python 2 говорит:

Во-первых, вкладки заменяются (слева направо) на один-восемь пробелов, так что общее количество символов, включая замену, должно быть кратным восьми (это предназначено для того же правила, что и в Unix ). Общее количество пробелов, предшествующих первому непустому символу, затем определяет отступ строки. Отступ нельзя разделить на несколько физических строк, используя обратную косую черту; пробел до первого обратного слеша определяет отступ.

Python 3 говорит:

Вкладки заменяются (слева направо) на один-восемь пробелов, так что общее количество символов до замены включительно умножается на восемь (это должно быть то же правило, которое используется в Unix). Общее количество пробелов, предшествующих первому непустому символу, затем определяет отступ строки. Отступ нельзя разделить на несколько физических строк, используя обратную косую черту; пробел до первого обратного слеша определяет отступ.

(Кроме вводного слова «Первый» они идентичны.)

Python 3 добавляет дополнительный абзац:

Отступы отклоняются как несогласованные, если исходный файл смешивает вкладки и пробелы таким образом, что значение зависит от значения вкладки в пробелах; В этом случае возникает ошибка TabError.

Это означает, что пример TAB против 8 пробелов, который работал в Python 2, сгенерирует TabError в Python 3. Лучше всего - в Python 3 - обеспечить, чтобы последовательность символов составляла отступ в каждой строке блока идентичен. PEP8 говорит: «используйте 4 пробела на уровень отступа». (Стандарты кодирования Google гласят: «используйте 2 пробела».)

18 голосов
/ 09 января 2010

Следуйте PEP 8 для стиля Python. ПКП 8 говорит: Отступы

Используйте 4 пробела на уровень отступа.

Для действительно старого кода, который вы не хотите испортить, вы можете продолжить использовать вкладки с 8 пробелами.

Вкладки или пробелы?

Никогда не смешивайте символы табуляции и пробелы.

Самый популярный способ сделать отступ в Python - использовать только пробелы. Второй по популярности способ только с вкладками. Код с отступом смесь вкладок и пробелов должна быть преобразована в использование пробелов исключительно. При вызове интерпретатора командной строки Python с опция -t выдает предупреждения о коде, который незаконно смешивает вкладки и пробелы. При использовании -tt эти предупреждения становятся ошибками. Эти варианты настоятельно рекомендуются!

8 голосов
/ 24 августа 2014

В Python 2 интерпретация TAB выглядит так, как будто она преобразуется в пробелы с использованием табуляции в 8 пробелов (как уже было указано в предыдущих ответах); то есть каждый TAB увеличивает отступ на 1-8 пробелов, так что полученный отступ делится на 8.

Однако это больше не относится к Python 3 - в Смешивание пробелов и вкладок в Python 3 всегда является ошибкой - вкладки соответствуют только вкладкам, а пробелы соответствуют только другим пробелам в отступе; строка с отступом TAB SPACE SPACE также может содержать строки с отступом SPACE SPACE TAB ; и может содержать блок с отступом с отступом TAB SPACE SPACE TAB , но если в нем блок с отступом содержал TAB TAB , это будет считаться ошибка отступа, даже если блок будет расширяться:

Отступы отклоняются как несогласованные, если исходный файл смешивает вкладки и пробелы таким образом, что значение зависит от значения вкладки в пробелах; В этом случае возникает ошибка TabError.

т.е. Алгоритм работает следующим образом:

  • если число табуляций и количество пробелов соответствуют предыдущей строке (независимо от порядка), то эта строка принадлежит тому же блоку, что и предыдущая строка

  • если номер одного из них (табуляции, пробелов) больше, чем в предыдущей строке, а номер другого по крайней мере равен номерам в предыдущей строке, это блок с отступом

  • кортеж (tabs, spaces) соответствует отступу из предыдущего блока - это отступ для этого блока

  • в противном случае IndentationError или TabError повышается.

Именно поэтому смешивание табуляции и пробелов или даже использование табуляции для отступов вообще считается очень плохой практикой в ​​Python.

5 голосов
/ 09 января 2010

Я бы порекомендовал вам пройти PEP 8 , который является "официальным" руководством по стилю Python для кода Python. Он охватывает (среди прочего) использование символов табуляции / пробелов.

5 голосов
/ 09 января 2010

Только не меняйте их:)
Установите вашу IDE / редактор для ввода 4 пробелов после нажатия клавиши «Tab», и все готово.

2 голосов
/ 09 января 2010

Четыре пробела - это одна вкладка (в моей настройке), но, насколько я знаю, они не взаимозаменяемы. Вы можете использовать пробелы или табуляции, но не оба.

0 голосов
/ 10 января 2010

Я считаю, что символ табуляции никогда не должен появляться в исходном коде ни при каких обстоятельствах. В этом нет никакого преимущества, и это бесконечный источник крошечных ошибок. - используйте символьную строку с \ t, если вам нужна вкладка, она имеет то преимущество, что она самодокументируется.

Здесь это классическая статья о вкладках против пробелов - я использую вариант elisp jwz в моем собственном файле .emacs.

(Признаюсь, что лично порвал с PEP 8, используя отступ только в 2 символа - 4 символа много, если в ваших строках всего 80 символов ...)

...