Відступ
Оновлено: 28.04.2023
Пробіли (пробіли та табуляції) на початку логічного рядка використовуються для обчислення рівня відступу рядка, який, у свою чергу, використовується для визначення групування операторів.
Табуляції замінюються (зліва направо) на один-вісім пробілів, щоб загальна кількість символів до заміни включно була кратною восьми (це те саме правило, яке використовується в Unix). Тоді загальна кількість пробілів перед першим символом, що не є пробілом, визначає відступ рядка. Відступи не можна розділити на кілька фізичних рядків за допомогою зворотної косої риски; пробіл до першої зворотної скісної риски визначає відступ.
Відступи відхиляються як непослідовні, якщо вихідний файл змішує табуляції та пробіли таким чином, що робить значення залежним від цінності табуляції в пробілах; У цьому випадку виникає TabError.
Примітка щодо крос-платформної сумісності: через характер текстових редакторів на платформах, відмінних від UNIX, нерозумно використовувати суміш пробілів і табуляції для відступу в одному вихідному файлі. Слід також зазначити, що різні платформи можуть явно обмежувати максимальний рівень відступу.
Символ переходу форми може бути присутнім на початку рядка; він буде проігнорований для обчислень відступів вище. Символи передачі форми, що зустрічаються в інших місцях у першому пробілі, мають невизначений ефект (наприклад, вони можуть скинути кількість пробілів до нуля).
Рівні відступів послідовних рядків використовуються для створення токенів INDENT і DEDENT за допомогою стека, як показано нижче.
Перш ніж буде зчитано перший рядок файлу, у стек вставляється один нуль; це ніколи більше не вискочить. Числа в стеку завжди суворо зростатимуть знизу вгору. На початку кожного логічного рядка рівень відступу рядка порівнюється з верхньою частиною стека. Якщо воно рівне, нічого не відбувається. Якщо він більший, він поміщається в стек і генерується один токен INDENT. Якщо воно менше, воно повинно бути одним із чисел, які зустрічаються в стеку; усі номери зі стеку, які є більшими, вилучаються, і для кожного числа, що виривається, генерується маркер DEDENT. У кінці файлу генерується маркер DEDENT для кожного числа, що залишилося в стеку і є більшим за нуль.
Ось приклад правильного (хоча і заплутаного) фрагмента коду Python з відступом:
def perm(l):
# Compute the list of all permutations of l
if len(l) <= 1:
return [l]
r = []
for i in range(len(l)):
s = l[:i] + l[i+1:]
p = perm(s)
for x in p:
r.append(l[i:i+1] + x)
return r
У наступному прикладі показано різні помилки відступів:
def perm(l): # error: first line indented
for i in range(len(l)): # error: not indented
s = l[:i] + l[i+1:]
p = perm(l[:i] + l[i+1:]) # error: unexpected indent
for x in p:
r.append(l[i:i+1] + x)
return r # error: inconsistent dedent
(Насправді, перші три помилки виявляються синтаксичним аналізатором; лише остання помилка знаходить лексичний аналізатор — відступ return r не відповідає рівню, витягненому зі стеку.)