Содержание страницы
7. Составные инструкции¶Compound statements
Составные инструкции содержат (группы) других инструкций; они влияют на выполнение этих других инструкций или управляют им. В общем случае составные инструкции охватывают несколько строк, хотя в простых вариантах вся составная инструкция может помещаться в одну строку.
Инструкции if, while и for реализуют традиционные конструкции управления потоком. try определяет обработчики исключений и/или код очистки для группы инструкций. Определения функций и классов также синтаксически являются составными инструкциями.
Составные инструкции состоят из одного или более «предложений». Предложение состоит из заголовка и «набора инструкций». Заголовки предложений конкретной составной инструкции находятся на одном уровне отступа. Каждый заголовок предложения начинается с уникального идентифицирующего ключевого слова и заканчивается двоеточием. Набор инструкций – это группа инструкций, управляемая предложением. Набор инструкций может быть одной или несколькими простыми инструкциями, разделёнными точкой с запятой, на той же строке, что и заголовок, после двоеточия заголовка, или одной или несколькими инструкциями с отступом на последующих строках. Только последняя форма набора инструкций может содержать вложенные составные инструкции; следующий пример недопустим, в основном потому, что было бы неясно, к какому предложению if относится последующее предложение else:
if test1: if test2: print x
Также обратите внимание, что в этом контексте точка с запятой связывает сильнее, чем двоеточие, поэтому в следующем примере будут выполнены либо все инструкции print, либо ни одна:
if x < y < z: print x; print y; print z
Подводя итог:
compound_stmt ::=if_stmt|while_stmt|for_stmt|try_stmt|with_stmt|funcdef|classdef|decoratedsuite ::=stmt_listNEWLINE | NEWLINE INDENTstatement+ DEDENT statement ::=stmt_listNEWLINE |compound_stmtstmt_list ::=simple_stmt(";"simple_stmt)* [";"]
Обратите внимание, что инструкции всегда заканчиваются NEWLINE, за которым возможно следует DEDENT. Также обратите внимание, что необязательные продолжения предложений всегда начинаются с ключевого слова, которое не может начинать инструкцию, поэтому неоднозначности отсутствуют (проблема «висячего else» в Python решается требованием отступа для вложенных инструкций if).
Форматирование грамматических правил в следующих разделах помещает каждое предложение на отдельную строку для ясности.
7.1. Инструкция if¶The if statement
Инструкция if используется для условного выполнения:
if_stmt ::= "if"expression":"suite( "elif"expression":"suite)* ["else" ":"suite]
Он выбирает ровно один из наборов инструкций, вычисляя выражения одно за другим,
пока одно из них не окажется истинным (см. раздел Булевы операции для определения
истины и лжи); затем этот набор выполняется (и никакая другая часть инструкции
if не выполняется и не вычисляется). Если все выражения
ложны, выполняется набор инструкций предложения else, если оно присутствует.
7.2. Инструкция while¶The while statement
Инструкция while используется для повторного выполнения, пока
выражение истинно:
while_stmt ::= "while"expression":"suite["else" ":"suite]
Эта инструкция многократно проверяет выражение и, если оно истинно, выполняет первый
набор инструкций; если выражение ложно (возможно, при первой проверке), то
набор инструкций предложения else, если оно присутствует, выполняется, и цикл
завершается.
Инструкция break, выполненная в первом наборе, завершает цикл,
не выполняя набор инструкций предложения else. Инструкция continue,
выполненная в первом наборе, пропускает оставшуюся часть набора и возвращается
к проверке выражения.
7.3. Инструкция for¶The for statement
Инструкция for используется для перебора элементов последовательности
(например, строки, кортежа или списка) или другого итерируемого объекта:
for_stmt ::= "for"target_list"in"expression_list":"suite["else" ":"suite]
Список выражений вычисляется один раз; он должен давать итерируемый объект. Для результата expression_list создаётся итератор. Затем набор инструкций выполняется один раз для каждого элемента, предоставленного итератором, в порядке возрастания индексов. Каждый элемент по очереди присваивается целевому списку с использованием стандартных правил присваивания, после чего выполняется набор инструкций. Когда элементы исчерпаны (что происходит немедленно, если последовательность пуста), выполняется набор инструкций в предложении else, если оно присутствует, и цикл завершается.
Инструкция break, выполненная в первом наборе инструкций, завершает цикл без выполнения набора инструкций предложения else. Инструкция continue, выполненная в первом наборе инструкций, пропускает оставшуюся часть набора инструкций и переходит к следующему элементу или к предложению else, если следующего элемента не было.
Блок может присваивать значения переменным в целевом списке; это не влияет на следующий присваиваемый элемент.
Целевой список не удаляется после завершения цикла, но если последовательность пуста, цикл вообще не присвоит ему никаких значений. Подсказка: встроенная функция range() возвращает последовательность целых чисел, подходящую для эмуляции эффекта паскалевского for i := a to b do; например, range(3) возвращает список [0, 1, 2].
Примечание
Существует тонкость, когда последовательность изменяется в цикле (это возможно только для изменяемых последовательностей, например списков). Для отслеживания того, какой элемент будет использован следующим, применяется внутренний счётчик, который увеличивается на каждой итерации. Когда этот счётчик достигает длины последовательности, цикл завершается. Это означает, что если набор инструкций удаляет текущий (или предыдущий) элемент из последовательности, следующий элемент будет пропущен (поскольку он получает индекс текущего элемента, который уже был обработан). Аналогично, если набор инструкций вставляет элемент в последовательность перед текущим элементом, текущий элемент будет обработан снова на следующем проходе цикла. Это может привести к неприятным ошибкам, которых можно избежать, создав временную копию с помощью среза всей последовательности, например:
for x in a[:]:
if x < 0: a.remove(x)
7.4. Инструкция try¶The try statement
Инструкция try задаёт обработчики исключений и/или код очистки
для группы инструкций:
try_stmt ::= try1_stmt | try2_stmt try1_stmt ::= "try" ":"suite("except" [expression[("as" | ",")identifier]] ":"suite)+ ["else" ":"suite] ["finally" ":"suite] try2_stmt ::= "try" ":"suite"finally" ":"suite
Изменено в версии 2.5: В предыдущих версиях Python try…except…finally не работали. try…except должны были быть вложены в try…finally.
Предложение(я) except задают один или несколько обработчиков исключений. Если в предложении try не возникает исключений, обработчик исключений не выполняется. Когда в наборе инструкций try возникает исключение, начинается поиск обработчика исключений. Этот поиск последовательно проверяет предложения except, пока не будет найдено подходящее исключение. Предложение except без выражения, если оно присутствует, должно быть последним; оно соответствует любому исключению. Для предложения except с выражением это выражение вычисляется, и предложение соответствует исключению, если полученный объект «совместим» с исключением. Объект совместим с исключением, если он является классом или базовым классом объекта исключения, или кортежем, содержащим элемент, совместимый с исключением.
Если ни одно предложение except не соответствует исключению, поиск обработчика исключений продолжается в окружающем коде и в стеке вызовов. 1
Если вычисление выражения в заголовке предложения except вызывает
исключение, исходный поиск обработчика отменяется, и начинается поиск
нового исключения в окружающем коде и в стеке вызовов (считается, что
исключение вызвано всей инструкцией try).
Когда найдено подходящее предложение except, исключение присваивается цели, указанной в этом предложении except, если она присутствует, и выполняется набор инструкций этого предложения except. Все предложения except должны иметь исполняемый блок. Когда конец этого блока достигнут, выполнение продолжается обычным образом после всего оператора try. (Это означает, что если существуют два вложенных обработчика для одного и того же исключения, и исключение возникает в предложении try внутреннего обработчика, внешний обработчик не будет обрабатывать исключение.)
Перед выполнением набора инструкций предложения except сведения об исключении присваиваются трём переменным в модуле sys: sys.exc_type получает объект, идентифицирующий исключение; sys.exc_value получает параметр исключения; sys.exc_traceback получает объект трассировки (см. раздел Стандартная иерархия типов), указывающий на точку в программе, где возникло исключение. Эти сведения также доступны через функцию sys.exc_info(), которая возвращает кортеж (exc_type, exc_value, exc_traceback). Использование соответствующих переменных считается устаревшим в пользу этой функции, так как их использование небезопасно в многопоточной программе. Начиная с Python 1.5, переменные восстанавливаются до своих предыдущих значений (до вызова) при возврате из функции, обработавшей исключение.
Необязательное предложение else выполняется, если поток управления покидает блок try, не было вызвано исключение и не выполнялся оператор return, continue или break. Исключения в предложении else не обрабатываются предшествующими предложениями except.
Если присутствует finally, он задаёт обработчик «очистки». Выполняется предложение try, включая любые предложения except и else. Если в каком-либо из предложений возникает исключение и оно не обрабатывается, исключение временно сохраняется. Выполняется предложение finally. Если есть сохранённое исключение, оно повторно возбуждается в конце предложения finally. Если предложение finally возбуждает другое исключение или выполняет инструкцию return или break, сохранённое исключение отбрасывается:
>>> def f():
... try:
... 1/0
... finally:
... return 42
...
>>> f()
42
Информация об исключении недоступна программе во время выполнения предложения finally.
Когда оператор return, break или continue выполняется в блоке try оператора try…finally, предложение finally также выполняется «по выходу». Оператор continue недопустим в предложении finally. (Причина – проблема текущей реализации; это ограничение может быть снято в будущем).
Возвращаемое значение функции определяется последней выполненной инструкцией return.
Поскольку предложение finally выполняется всегда, инструкция
return, выполненная в предложении finally, всегда будет последней выполненной:
>>> def foo():
... try:
... return 'try'
... finally:
... return 'finally'
...
>>> foo()
'finally'
Дополнительную информацию об исключениях можно найти в разделе Исключения,
а информация об использовании инструкции raise для генерации исключений
приведена в разделе Инструкция raise.
7.5. Инструкция with¶The with statement
Новое в версии 2.5.
Инструкция with используется для обёртывания выполнения блока методами, определёнными контекстным менеджером (см. раздел Контекстные менеджеры оператора with). Это позволяет инкапсулировать распространённые шаблоны использования try…except…finally для удобного повторного использования.
with_stmt ::= "with" with_item ("," with_item)* ":" suite
with_item ::= expression ["as" target]
Выполнение оператора with с одним «элементом» происходит следующим образом:
Контекстное выражение (выражение, указанное в
with_item) вычисляется для получения менеджера контекста.Метод
__exit__()контекстного менеджера загружается для последующего использования.Метод
__enter__()контекстного менеджера вызывается.Если в операторе
withбыла указана цель, возвращаемое значение из__enter__()присваивается ей.Примечание
Инструкция
withгарантирует, что если метод__enter__()возвращается без ошибки, то__exit__()будет вызван всегда. Таким образом, если ошибка возникает во время присваивания целевому списку, она будет обрабатываться так же, как ошибка, возникающая внутри набора инструкций. См. шаг 6 ниже.Выполняется блок.
Вызывается метод
__exit__()контекстного менеджера. Если исключение привело к выходу из набора инструкций, его тип, значение и трассировка передаются в качестве аргументов в__exit__(). В противном случае передаются три аргументаNone.Если набор инструкций был завершён из-за исключения и возвращаемое значение метода
__exit__()было ложным, исключение возбуждается повторно. Если возвращаемое значение было истинным, исключение подавляется, и выполнение продолжается с инструкции, следующей за операторомwith.Если набор инструкций был завершён по любой причине, кроме исключения, возвращаемое значение из
__exit__()игнорируется, и выполнение продолжается в обычном месте для того типа завершения, который был выполнен.
При наличии нескольких элементов менеджеры контекста обрабатываются так, как если бы несколько
операторов with были вложены:
with A() as a, B() as b:
suite
эквивалентна
with A() as a:
with B() as b:
suite
Примечание
В Python 2.5 инструкция with разрешена только при включённой возможности with_statement. В Python 2.6 она всегда включена.
Изменено в версии 2.7: Поддержка нескольких контекстных выражений.
7.6. Определения функций¶Function definitions
Определение функции создаёт объект пользовательской функции (см. раздел Стандартная иерархия типов):
decorated ::= decorators (classdef | funcdef) decorators ::=decorator+ decorator ::= "@"dotted_name["(" [argument_list[","]] ")"] NEWLINE funcdef ::= "def"funcname"(" [parameter_list] ")" ":"suitedotted_name ::=identifier("."identifier)* parameter_list ::= (defparameter",")* ( "*"identifier["," "**"identifier] | "**"identifier|defparameter[","] ) defparameter ::=parameter["="expression] sublist ::=parameter(","parameter)* [","] parameter ::=identifier| "("sublist")" funcname ::=identifier
Определение функции – это исполняемый оператор. Его выполнение связывает имя функции в текущей локальной области видимости с объектом функции (обёрткой над исполняемым кодом функции). Этот объект функции содержит ссылку на текущую глобальную область видимости, которая будет использоваться при вызове функции.
Определение функции не выполняет тело функции; оно выполняется только при вызове функции. 2
Определение функции может быть обёрнуто одним или несколькими выражениями декоратора. Выражения декоратора вычисляются при определении функции в области видимости, содержащей определение функции. Результат должен быть вызываемым объектом, который вызывается с объектом функции в качестве единственного аргумента. Возвращаемое значение привязывается к имени функции вместо объекта функции. Несколько декораторов применяются вложенным образом. Например, следующий код:
@f1(arg)
@f2
def func(): pass
эквивалентно:
def func(): pass
func = f1(arg)(f2(func))
Когда один или несколько параметров верхнего уровня имеют форму параметр = выражение, говорят, что функция имеет «значения параметров по умолчанию». Для параметра со значением по умолчанию соответствующий аргумент может быть опущен при вызове, в этом случае подставляется значение параметра по умолчанию. Если параметр имеет значение по умолчанию, все последующие параметры также должны иметь значение по умолчанию – это синтаксическое ограничение, не выраженное в грамматике.
Значения параметров по умолчанию вычисляются при выполнении определения функции. Это означает, что выражение вычисляется один раз при определении функции, и для каждого вызова используется одно и то же «предвычисленное» значение. Это особенно важно понимать, когда параметр по умолчанию является изменяемым объектом, например списком или словарём: если функция модифицирует объект (например, добавляя элемент в список), значение по умолчанию фактически изменяется. Обычно это не соответствует замыслу. Обходной путь – использовать None в качестве значения по умолчанию и явно проверять его в теле функции, например:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
Семантика вызова функций более подробно описана в разделе Вызовы. Вызов функции всегда присваивает значения всем параметрам, перечисленным в списке параметров, либо из позиционных аргументов, либо из ключевых аргументов, либо из значений по умолчанию. Если присутствует форма «*identifier», она инициализируется кортежем, принимающим любые избыточные позиционные параметры; по умолчанию – пустой кортеж. Если присутствует форма «**identifier», она инициализируется новым словарём, принимающим любые избыточные ключевые аргументы; по умолчанию – новый пустой словарь.
Также можно создавать анонимные функции (функции, не привязанные к имени) для непосредственного использования в выражениях. Для этого используются лямбда-выражения, описанные в разделе Лямбда-выражения. Обратите внимание, что лямбда-выражение – это всего лишь сокращение для упрощённого определения функции; функция, определённая в операторе «def», может быть передана или присвоена другому имени точно так же, как функция, определённая лямбда-выражением. Форма «def» на самом деле более мощная, поскольку позволяет выполнять несколько инструкций.
Примечание программисту: Функции – объекты первого класса. Форма «def», выполненная внутри определения функции, определяет локальную функцию, которую можно вернуть или передать. Свободные переменные, используемые во вложенной функции, могут обращаться к локальным переменным функции, содержащей def. Подробнее см. раздел Именование и связывание.
7.7. Определения классов¶Class definitions
Определение класса создаёт объект класса (см. раздел Стандартная иерархия типов):
classdef ::= "class"classname[inheritance] ":"suiteinheritance ::= "(" [expression_list] ")" classname ::=identifier
Определение класса является исполняемой инструкцией. Сначала вычисляется список наследования, если он есть. Каждый элемент списка наследования должен быть классом или типом класса, допускающим наследование. Затем тело класса выполняется в новом кадре выполнения (см. раздел Именование и связывание) с использованием только что созданного локального пространства имён и исходного глобального пространства имён. (Обычно тело содержит только определения функций.) После завершения выполнения тела класса его кадр выполнения отбрасывается, но локальное пространство имён сохраняется. 3 Затем создаётся объект класса с использованием списка наследования для базовых классов и сохранённого локального пространства имён для словаря атрибутов. Имя класса связывается с этим объектом класса в исходном локальном пространстве имён.
Примечание программисту: Переменные, определённые в определении класса, являются переменными класса; они разделяются всеми экземплярами. Чтобы создать переменные экземпляра, их можно установить в методе с помощью self.name = value. Как переменные класса, так и переменные экземпляра доступны через запись «self.name», и переменная экземпляра скрывает переменную класса с тем же именем при таком доступе. Переменные класса можно использовать как значения по умолчанию для переменных экземпляра, но использование изменяемых значений может привести к неожиданным результатам. Для классов нового стиля можно использовать дескрипторы для создания переменных экземпляра с различными деталями реализации.
Определения классов, как и определения функций, могут быть обёрнуты одним или несколькими выражениями декоратора. Правила вычисления выражений декоратора такие же, как для функций. Результатом должен быть объект класса, который затем связывается с именем класса.
Сноски
- 1
Исключение распространяется по стеку вызовов, если только не встретится предложение
finally, которое в свою очередь возбуждает другое исключение. Это новое исключение приводит к потере старого.- 2
Строковый литерал, появляющийся как первая инструкция в теле функции, преобразуется в атрибут
__doc__функции и, следовательно, в докстринг функции.- 3
Строковый литерал, появляющийся в качестве первого оператора в теле класса, преобразуется в элемент
__doc__пространства имён и, следовательно, в докстринг класса.