executionmodel.md
1> **Источник:** https://python-all.ru/2.7/reference/executionmodel.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 4. Модель выполнения89## 4.1. Именование и связывание1011*Имена* ссылаются на объекты. Имена вводятся операциями связывания имени. Каждое вхождение имени в тексте программы ссылается на *связывание* этого имени, установленное в самом внутреннем блоке функции, содержащем использование.1213*Блок* – это часть текста программы на Python, которая выполняется как единое целое. Блоками являются: модуль, тело функции и определение класса. Каждая команда, введённая в интерактивном режиме, является блоком. Файл сценария (файл, переданный в качестве стандартного ввода интерпретатору или указанный в командной строке интерпретатора первым аргументом) является блоком кода. Команда сценария (команда, указанная в командной строке интерпретатора с опцией ‘**-c**’) является блоком кода. Файл, читаемый встроенной функцией [`execfile()`](https://python-all.ru/2.7/library/functions.html#execfile), является блоком кода. Строковый аргумент, переданный встроенной функции [`eval()`](https://python-all.ru/2.7/library/functions.html#eval) и оператору [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec), является блоком кода. Выражение, которое читается и вычисляется встроенной функцией [`input()`](https://python-all.ru/2.7/library/functions.html#input), является блоком кода.1415Блок кода выполняется в *фрейме выполнения*. Фрейм содержит некоторую служебную информацию (используемую для отладки) и определяет, где и как продолжится выполнение после завершения выполнения блока кода.1617*Область видимости* определяет видимость имени в пределах блока. Если локальная переменная определена в блоке, её область видимости включает этот блок. Если определение находится в блоке функции, область видимости распространяется на любые блоки, содержащиеся в определяющем, если только содержащийся блок не вводит другую привязку для имени. Область видимости имён, определённых в блоке класса, ограничена блоком класса; она не распространяется на блоки кода методов – это включает генераторные выражения, поскольку они реализованы с использованием области видимости функции. Это означает, что следующий код завершится ошибкой:1819```python20class A:21 a = 4222 b = list(a + i for i in range(10))23```2425Когда имя используется в блоке кода, оно разрешается с помощью ближайшей объемлющей области видимости. Множество всех таких областей, видимых блоку кода, называется его *окружением*.2627Если имя связывается в блоке, оно является локальной переменной этого блока. Если имя связывается на уровне модуля, оно является глобальной переменной. (Переменные блока кода модуля являются как локальными, так и глобальными.) Если переменная используется в блоке кода, но не определена в нём, она является *свободной переменной*.2829Если имя не найдено вовсе, возникает исключение [`NameError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.NameError). Если имя ссылается на локальную переменную, которая не была связана, возникает исключение [`UnboundLocalError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.UnboundLocalError). [`UnboundLocalError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.UnboundLocalError) является подклассом [`NameError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.NameError).3031Следующие конструкции связывают имена: формальные параметры функций, операторы [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import), определения классов и функций (они связывают имя класса или функции в определяющем блоке), а также цели, являющиеся идентификаторами, если они встречаются в присваивании, заголовке цикла [`for`](https://python-all.ru/2.7/reference/compound_stmts.html#for), во второй позиции заголовка предложения [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) или после [`as`](https://python-all.ru/2.7/reference/compound_stmts.html#as) в операторе [`with`](https://python-all.ru/2.7/reference/compound_stmts.html#with). Оператор [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import) вида `from ... import *` связывает все имена, определённые в импортируемом модуле, за исключением тех, которые начинаются с подчёркивания. Эта форма может использоваться только на уровне модуля.3233Цель, встречающаяся в операторе [`del`](https://python-all.ru/2.7/reference/simple_stmts.html#del), также считается связанной для этой цели (хотя фактическая семантика заключается в отвязывании имени). Незаконно отвязывать имя, на которое ссылается внешняя область видимости; компилятор сообщит об ошибке [`SyntaxError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SyntaxError).3435Каждый оператор присваивания или импорта находится внутри блока, определённого классом или определением функции, либо на уровне модуля (блок кода верхнего уровня).3637Если операция связывания имени происходит где-либо внутри блока кода, все использования имени внутри блока рассматриваются как ссылки на текущий блок. Это может привести к ошибкам, когда имя используется внутри блока до того, как оно связано. Это правило тонкое. В Python нет объявлений, и операции связывания имени могут происходить в любом месте блока кода. Локальные переменные блока кода можно определить, просканировав весь текст блока на предмет операций связывания имени.3839Если оператор global встречается внутри блока, все использования имени, указанного в операторе, ссылаются на связывание этого имени в пространстве имён верхнего уровня. Имена разрешаются в пространстве имён верхнего уровня путём поиска в глобальном пространстве имён, т.е. пространстве имён модуля, содержащего блок кода, и в пространстве имён встроенных функций (builtins), пространстве имён модуля [`__builtin__`](https://python-all.ru/2.7/library/__builtin__.html#module-__builtin__). Сначала ищется глобальное пространство имён. Если имя не найдено там, ищется пространство имён встроенных функций. Оператор global должен предшествовать всем использованиям имени.4041Пространство имён встроенных функций, связанное с выполнением блока кода, на самом деле находится путём поиска имени `__builtins__` в его глобальном пространстве имён; это должно быть словарь или модуль (в последнем случае используется словарь модуля). По умолчанию, когда находимся в модуле [`__main__`](https://python-all.ru/2.7/library/__main__.html#module-__main__), `__builtins__` – это встроенный модуль [`__builtin__`](https://python-all.ru/2.7/library/__builtin__.html#module-__builtin__) (обратите внимание: без ‘s’); когда в любом другом модуле, `__builtins__` является псевдонимом для словаря самого модуля [`__builtin__`](https://python-all.ru/2.7/library/__builtin__.html#module-__builtin__). `__builtins__` можно установить в словарь, созданный пользователем, чтобы создать слабую форму ограниченного выполнения.4243**Детали реализации CPython:** Пользователи не должны трогать `__builtins__`; это строго деталь реализации. Пользователи, желающие переопределить значения в пространстве имён встроенных функций, должны [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import) модуль [`__builtin__`](https://python-all.ru/2.7/library/__builtin__.html#module-__builtin__) (без ‘s’) и соответствующим образом изменить его атрибуты.4445Пространство имён модуля автоматически создаётся при первом импорте модуля. Главный модуль скрипта всегда называется [`__main__`](https://python-all.ru/2.7/library/__main__.html#module-__main__).4647Оператор [`global`](https://python-all.ru/2.7/reference/simple_stmts.html#global) имеет ту же область видимости, что и операция связывания имени в том же блоке. Если ближайшая охватывающая область видимости для свободной переменной содержит оператор global, свободная переменная считается глобальной.4849Определение класса – это исполняемый оператор, который может использовать и определять имена. Эти ссылки следуют обычным правилам разрешения имён. Пространство имён определения класса становится словарём атрибутов класса. Имена, определённые на уровне класса, не видны в методах.5051### 4.1.1. Взаимодействие с динамическими возможностями5253Есть несколько случаев, когда инструкции Python недопустимы при использовании в сочетании с вложенными областями видимости, содержащими свободные переменные.5455Если переменная используется в охватывающей области видимости, удаление этого имени недопустимо. Ошибка будет сообщена на этапе компиляции.5657Если форма импорта со звёздочкой – `import *` – используется в функции и функция содержит вложенный блок со свободными переменными или сама является таким блоком, компилятор вызовет исключение [`SyntaxError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SyntaxError).5859Если [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec) используется в функции и функция содержит вложенный блок со свободными переменными или сама является таким блоком, компилятор вызовет исключение [`SyntaxError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SyntaxError), если только exec явно не указывает локальное пространство имён для [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec). (Другими словами, `exec obj` было бы недопустимо, а `exec obj in ns` – допустимо.)6061Функции [`eval()`](https://python-all.ru/2.7/library/functions.html#eval), [`execfile()`](https://python-all.ru/2.7/library/functions.html#execfile) и [`input()`](https://python-all.ru/2.7/library/functions.html#input), а также оператор [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec) не имеют доступа к полному окружению для разрешения имён. Имена могут разрешаться в локальном и глобальном пространствах имён вызывающего кода. Свободные переменные разрешаются не в ближайшем внешнем пространстве имён, а в глобальном пространстве имён. [1](https://python-all.ru/2.7/reference/executionmodel.html#id3) Оператор [`exec`](https://python-all.ru/2.7/reference/simple_stmts.html#exec) и функции [`eval()`](https://python-all.ru/2.7/library/functions.html#eval) и [`execfile()`](https://python-all.ru/2.7/library/functions.html#execfile) имеют необязательные аргументы для переопределения глобального и локального пространства имён. Если указано только одно пространство имён, оно используется для обоих.6263## 4.2. Исключения6465Исключения – это способ выйти из нормального потока управления блока кода, чтобы обработать ошибки или другие исключительные ситуации. Исключение *возбуждается* в том месте, где обнаружена ошибка; оно может быть *перехвачено* окружающим блоком кода или любым блоком, который прямо или косвенно вызвал блок кода, где произошла ошибка.6667Интерпретатор Python возбуждает исключение, когда обнаруживает ошибку времени выполнения (например, деление на ноль). Программа на Python также может явно возбудить исключение с помощью оператора [`raise`](https://python-all.ru/2.7/reference/simple_stmts.html#raise). Обработчики исключений задаются с помощью оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) … [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except). Предложение [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally) такого оператора можно использовать для указания кода очистки, который не обрабатывает исключение, но выполняется независимо от того, было ли исключение в предшествующем коде.6869В Python используется модель обработки ошибок с «завершением»: обработчик исключений может выяснить, что произошло, и продолжить выполнение на внешнем уровне, но он не может исправить причину ошибки и повторить сбойную операцию (кроме случая повторного входа в проблемный кусок кода с самого начала).7071Когда исключение не обрабатывается совсем, интерпретатор завершает выполнение программы или возвращается в свой интерактивный главный цикл. В любом случае он печатает стековую трассировку, за исключением случая, когда исключением является [`SystemExit`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SystemExit).7273Исключения идентифицируются экземплярами классов. Предложение [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) выбирается в зависимости от класса экземпляра: оно должно ссылаться на класс экземпляра или один из его базовых классов. Экземпляр может быть получен обработчиком и может содержать дополнительную информацию об исключительной ситуации.7475Исключения также могут быть идентифицированы строками, и в этом случае предложение [`except`](https://python-all.ru/2.7/reference/compound_stmts.html#except) выбирается по идентичности объекта. Вместе с идентифицирующей строкой может быть возбуждено произвольное значение, которое может быть передано обработчику.7677> **Примечание**78>79> Сообщения исключений не являются частью Python API. Их содержимое может меняться от версии Python к версии без предупреждения, и на него не следует полагаться в коде, который будет выполняться под несколькими версиями интерпретатора.8081См. также описание оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) в разделе [Оператор try](https://python-all.ru/2.7/reference/compound_stmts.html#try) и оператора [`raise`](https://python-all.ru/2.7/reference/simple_stmts.html#raise) в разделе [Оператор raise](https://python-all.ru/2.7/reference/simple_stmts.html#raise).8283Сноски8485**[1](https://python-all.ru/2.7/reference/executionmodel.html#id1)**8687Это ограничение возникает из-за того, что код, выполняемый этими операциями, недоступен во время компиляции модуля.88