The Python Language Reference / Справочник по языку Python: 7. Compound statements
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
7. Составные инструкции Hittih 08.09.10 в 04:19 |
|
|
Составные инструкции содержат другие инструкции или их группы. Они влияют, или прямо контролируют исполнение содержащихся инструкций каким-либо образом. Как правило составные инструкции состоят из нескольких строк, однако в простых выражениях составная инструкция может целиком размещаться в одной строке. Hittih 08.09.10 в 01:30 |
||
|
Инструкции «if», «while» и «for» реализуют стандартные конструкции управления потоком исполнения. «try» определяет для определённой группы выражений обработчик исключения и/или код ликвидации последствий, тогда как инструкция «with» позволяет исполнять инициализирующий и завершающий код соответственно до и после определённого кода. Определения функций и классов синтаксически также являются составными инструкциями. Hittih 08.09.10 в 01:52 |
||
|
Составные инструкции состоят из одной или более «групп» . Группа состоит из «заголовка» и «содержимого» . Все «заголовки» групп одной составной инструкции находятся на одном уровне отступов. Каждый «заголовок» группы начинается с однозначно идентифицирующего ключевого слова и заканчивается двоеточием. Инструкции «содержимого» являются подконтрольными в группе . «Содержимое» может быть одной или более простыми инструкциями разделенными точкой с запятой в той же строке, что и «заголовок» , после двоеточия «заголовка» , или же может быть одной или более инструкций, идущих в отдельных строках с отступом. Только последняя форма содержимого группы может содержать вложенные составные инструкции. Следующий пример недопустим, главным образом потому, что не ясно, группе которого «if» будет относиться группа следующего «else» : Hittih 08.09.10 в 04:16 |
||
|
if test1: if test2: print(x) RedFox 10.08.10 в 19:23 |
||
|
К тому же заметьте, что (в данном контексте) точка-с-запятой связывается сильнее, чем двоеточие, таким образом в следующем примере исполняются или все инструкции «print()» , или ни одной : Hittih 08.09.10 в 04:26 |
||
|
if x < y < z: print(x); print(y); print(z) RedFox 10.08.10 в 19:23 |
||
|
В итоге : Hittih 08.09.10 в 04:28 |
||
|
compound_stmt ::= if_stmt Hittih 08.09.10 в 04:30 |
||
|
Заметьте, что инструкции всегда заканчиваются признаком «NEWLINE» , после которого может идти «DEDENT» . Также отметьте, что необязательные ветви в условиях всегда начинаются с такого ключевого слова, по которому ясно, что это именно продолжение инструкции необязательною ветвью, и с этого слова не может начинаться новая инструкция. Проблема “оторванных” «else» решена в Питоне через обязательность отступов для вложенных «if» . Hittih 12.12.11 в 09:04 |
||
|
В следующих описаниях грамматических правил для удобочитаемости каждая формула размещается с новой строки. Hittih 12.12.11 в 09:17 |
||
|
7.1 Инструкция «if» Hittih 08.09.10 в 19:31 |
||
|
Инструкция «if» служит для исполнения по условию : Hittih 08.09.10 в 19:33 |
||
|
if_stmt ::= "if" expression ":" suite Hittih 08.09.10 в 19:34 |
||
|
Инструкция «if» выбирает только одну вложенную группу инструкций, вычисляя выражения-условия по очереди до первого со значением «True» (смотрите раздел «Логические (булевы) операции» ) , затем соответствующая вложенная группа исполняется (и больше не вычисляются другие выражения-условия и не выполняются другие группы) . Если все выражения-условия имеют значение «False» , то вложенная группа ветви «else» выполняется, если присутствует. Hittih 08.09.10 в 20:21 |
||
|
7.2 Инструкция «while» Hittih 08.09.10 в 20:23 |
||
|
Инструкция «while» используется для циклического исполнения пока выражение истинно : Hittih 08.09.10 в 20:26 |
||
|
while_stmt ::= "while" expression ":" suite ["else" ":" suite] Hittih 08.09.10 в 20:26 |
||
|
Инструкция «while» циклически проверяет выражение-условие, и если оно истинно – выполняет первую вложенную группу, а если оно ложно – (даже если это происходит при первой же проверке) цикл завершается и вложенная группа ветви «else» выполняется, если присутствует. Hittih 08.09.10 в 20:41 |
||
|
Исполнение инструкции «break» в первой группе прекращает цикл без исполнения ветви «else» . Инструкция «continue» в первой группе пропускает остаток этой группы, и происходит переход обратно к проверке выражения-условия. Hittih 08.09.10 в 21:05 |
||
|
7.3 Инструкция «for» Hittih 08.09.10 в 21:06 |
||
|
Инструкция «for» используется для того, чтобы перебирать последовательно элементы последовательности (например текстовые данные, «кортежи» , списки) или другого перечислимого объекта : Hittih 08.09.10 в 21:11 |
||
|
for_stmt ::= "for" target_list "in" expression_list ":" suite Hittih 08.09.10 в 21:12 |
||
|
Список выражений «expression_list» вычисляется только один раз – он должен давать в результате итерируемый объект, для которого создаётся итератор. Вложенный блок затем исполняется по одному разу для каждого элемента, выданного итератором в порядке увеличения индексов. Каждый такой выданный итератором элемент назначается списку целей в соответствии со стандартными правилами назначения (смотрите раздел 6.2. «Инструкции назначения») , и затем уже́ вложенный блок исполняется. Когда эти элементы кончаются (в самом начале, если последовательность пустая, или когда итератор инициирует исключение «StopIteration» ) , то исполняется блок инструкций ветви «else» , если таковая присутствует, и цикл прекращается. Hittih 23.09.10 в 09:31 |
||
|
Инструкция «break» , исполненная в основной ветви («for») , прекращает цикл без исполнения ветви «else» . Инструкция «continue» , исполненная в основной ветви («for») , пропускает оставшиеся инструкции блока и, если итерируемые элементы ещё есть – переходит к новому исполнению блока со следующим элементом, а иначе переходит к ветви «else» . Hittih 23.09.10 в 10:28 |
||
|
Внутри вложенного блока можно изменять значение переменных из списка целей, и это ни как не повлияет на их значение, когда при следующем проходе им будет назначено значение очередного элемента. Hittih 23.09.10 в 10:39 |
||
|
Имена из списка целей не удаляются после окончания цикла, но, если последовательность пустая, то этим именам вообще не будет назначено значение (и, если переменные не существовали, то и не будут созданы) . Подсказка : встроенная функция «range()» возвращает итератор целых чисел, который можно использовать для эмулирования эффекта Паскалевского «for i := a to b do» , например, «list(range(3))» возвращает список «[0, 1, 2]» . Hittih 23.09.10 в 10:59 |
||
|
Замечание. Есть тонкость, когда итерируемая последовательность изменяется внутри цикла (это может произойти только с изменяемыми последовательностями, например списком) . Для отслеживания того, какой элемент будет использован следующим, – используется внутренний счётчик, увеличиваемый на единицу при каждом проходе. Когда он достигает длинны последовательности – цикл прекращается. Это значит, что если внутри блока цикла удаляется текущий (или один из предыдущих) элемент последовательности, то элемент, который должен был быть выдан следующим будет пропущен, поскольку он получит индекс элемента, обрабатываемого в данный момент. Таким же образом, если внутри блока цикла в последовательность добавляется элемент до текущего элемента, то текущий элемент будет обработан ещё раз на следующем проходе цикла. Это может приводить к очень неприятным ошибкам, которых можно избежать, если для последовательности делать временную копию, с помощью среза всей последовательности, например : Hittih 23.09.10 в 13:58 |
||
|
<pre style="margin-bottom: 0em; margin-top: 0em;">for x in a[:]:<br /> if x < 0: a.remove(x)</pre> Hittih 23.09.10 в 14:04 |
||
|
7.4. Инструкция «try» Hittih 23.09.10 в 14:30 |
||
|
Инструкция «try» задаёт обработчики исключения и/или завершающий код для блока инструкций : Hittih 23.09.10 в 14:33 |
||
|
<code>try_stmt ::= try1_stmt | try2_stmt Hittih 23.09.10 в 14:34 |
||
|
Ветвь «<code>except</code>» задаёт один или более обработчиков исключений. Если не происходит ни одного исключения в соответствующей ветви «<code>try</code>» , то никакой из этих обработчиков не вызывается. Когда случается какое-либо исключение в соответствующей ветви «<code>try</code>» , то начинается поиск обработчика этого исключения. При этом поиске просматриваются последовательно все блоки «<code>except</code>» пока не встретится первый блок соответствующий произошедшему исключению. Если задан блок «<code>except</code>» без указания исключения , который подразумевает любое исключение, то его логично указывать последним. Для инструкции «<code>except</code>» с выражением – это выражение вычисляется, и если объект-результат является “совместимым” с обрабатываемым исключением, то данный блок «<code>except</code>» соответствует данному исключению. Объект совместим с данным исключением, если он является классом или базовым классом данного исключения, или же является кортежем, содержащим объект, совместимый с данным исключением. Hittih 19.10.11 в 13:11 |
||
|
Если не найдено ни одного блока «<code>except</code>» , соответствующего исключению, то поиск продолжается в окружающем коде и по стеку вызовов. Hittih 19.10.11 в 13:30 |
||
|
Исключение передаётся вверх по стеку вызовов только если отсутствует блок «<code>finally</code>» , нейтрализующий данное исключение. Hittih 19.10.11 в 13:35 Исключение передаётся вверх по стеку вызовов только если отсутствует блок «<code>finally</code>» , такой, который нейтрализует данное исключение. Hittih 31.10.11 в 20:29 |
||
|
Если при вычислении выражения у само́й инструкции «<code>except</code>» возникает исключение, то обработка текущего исключения (возникшего внутри блока «<code>try</code>» , к которому относится данная инструкция «<code>except</code>» ) отменяется, и начинается поиск обработчика для этого нового исключения в объемлющем коде и по стеку вызовов (тоесть, считается, что исключение вызвала вся конструкция «<code>try</code>» ) . Hittih 31.10.11 в 20:59 |
||
|
Если найдена соответствующая ветвь «<code>except</code>» , то внутри этой ветви данное исключение назначается получателю, указанному после ключевого слова «<code>as</code>» , если таковое присутствует, и затем блок кода этой ветви «<code>except</code>» исполняется. Все ветви «<code>except</code>» должны иметь исполнимый блок. Когда исполнение этого блока завершается – обработка данного исключения завершена, и исполнение продолжается уже́ обычным образом после всей конструкции «<code>try</code>» . (Это также значит, что если есть два вложенных обработчика для одного вида исключения, то когда оно происходит внутри внутренней ветви «<code>try</code>» – внешний обработчик не получит этого исключения.) Hittih 04.11.11 в 02:28 |
||
|
Если исключение назначается переменной, указанной после ключевого слова «<code>as</code>» , то она автоматически удаляется при завершении этого блока «<code>except</code>» , как если бы Hittih 04.11.11 в 02:38 |
||
|
<code>except E as N: Hittih 04.11.11 в 02:39 |
||
|
транслировалось в Hittih 04.11.11 в 02:40 |
||
|
<code>except E as N: Hittih 04.11.11 в 02:41 |
||
|
Из этого следует, что если нужно иметь возможность обращаться к данному объекту-исключению после завершения блока «<code>except</code>» , то нужно назначить это исключение ещё какому-либо имени. Причиной этого является то, что исключения со связанной с ними трассировкой образуют циклические ссылки с кадром стека, из-за чего все локальные переменные в этом кадре будут сохраняться до следующего сбора мусора. Hittih 04.11.11 в 03:57 |
||
|
Перед исполнением блока кода ветви «<code>except</code>» информация об исключении записывается в модуль «<code>sys</code>» и её можно получить с помощью «<code>sys.exc_info()</code>» . «<code>sys.exc_info()</code>» возвращает тройной кортеж, содержащий : «<code>exc_type</code>» – класс данного исключения; «<code>exc_value</code>» – экземпляр исключения; «<code>exc_traceback</code>» – объект трассировки (смотрите раздел об иерархии стандартных типов) указывающий место программы, в котором произошло исключение. Значения «<code>sys.exc_info()</code>» восстанавливаются в их предыдущее значение при возвращении из функции обработки исключения. Hittih 04.11.11 в 04:39 |
||
|
Необязательная ветвь «<code>else</code>» исполняется только если и когда происходит выход из блока «<code>try</code>» в связи с его исчерпанием, а не в связи с исключением или исполнением инструкций «<code>return</code>» , «<code>continue</code>» или «<code>break</code>» . Исключения в такой ветви «<code>else</code>» не обрабатываются идущими перед нею ветвями «<code>except</code>» (относящимися к той же конструкции «<code>try</code>») , а являются исключением, возникшим в целой этой конструкции «<code>try</code>» (и обрабатываются во внешнем коде) . Hittih 04.11.11 в 05:25 |
||
|
- Hittih 04.11.11 в 05:25 |
||
|
Если присутствует ветвь «<code>finally</code>» , то она определяет завершающий (зачищающий) обработчик. Выполняется ветвь «<code>try</code>» , а также все ветви «<code>except</code>» и «<code>else</code>» . Если в любой из них происходит исключение, и оно не обработано, то оно временно сохраняется. Затем выполняется ветвь «<code>finally</code>» . Затем, если было сохранено исключение, оно вызывается заново по завершении ветви «<code>finally</code>» . Если в ветви «<code>finally</code>» происходит исключение или исполняется инструкция «<code>return</code>» или «<code>break</code>» , то сохранённое исключение теряется. Информация об сохранённом исключении не доступна программе во время исполнения ветви «<code>finally</code>» . Hittih 21.11.11 в 20:18 |
||
|
Если в ветви «<code>try</code>» исполняется инструкция «<code>return</code>» или «<code>break</code>» , то ветвь «<code>finally</code>» тоже исполняется перед выходом из всей конструкции «<code>try...finally</code>» . В ветви «<code>finally</code>» инструкция «<code>continue</code>» недопустима. (Проблема в текущей реализации – это ограничение может быть снято в будущем.) Hittih 21.11.11 в 20:43 |
||
|
Дополнительная информация об исключениях есть в разделе “Исключения” , а об использовании инструкции «<code>raise</code>» для вызова исключений – в разделе “Инструкция «raise»” . Hittih 21.11.11 в 20:56 |
||
|
- Hittih 21.11.11 в 20:56 |
||
|
7.5. Инструкция «<code>with</code>» Hittih 21.11.11 в 20:58 |
