Модель выполнения
4.1. Структура программы
Программа Python состоит из блоков кода. Блок — это часть текста программы Python, выполняемая как единица. К блокам относятся: модуль, тело функции и определение класса. Каждая команда, введенная в интерактивном режиме, является блоком. Файл сценария (файл, переданный в качестве стандартного ввода интерпретатору или указанный в качестве аргумента командной строки интерпретатору) является блоком кода. Команда сценария (команда, указанная в командной строке интерпретатора с -c параметром) является блоком кода. Модуль, запущенный как скрипт верхнего уровня (как модуль __main__) из командной строки с помощью -m аргумента, также является блоком кода. Строковый аргумент, передаваемый встроенным функциям eval() и exec(), является блоком кода.
Блок кода выполняется в кадре выполнения. Кадр содержит некоторую служебную информацию (используемую для отладки) и определяет, где и как выполнение продолжается после завершения выполнения блока кода.
4.2. Имена и привязка
4.2.1. Привязка имён
Имена ссылаются на объекты. Имена вводятся операциями привязки имён.
Следующие конструкции привязывают имена:
- формальные параметры функций,
- определения классов,
- определения функций,
- выражения присваивания,
-
цели, которые являются идентификаторами, если они встречаются в присваивании:
-
importоператоры.
Оператор import вида from ... import * привязывает все имена, определённые в импортированном модуле, за исключением тех, которые начинаются с нижнего подчёркивания. Этот вид оператора может использоваться только на уровне модуля.
Цель, встречающаяся в операторе del, также считается привязанной для этой цели (хотя фактическая семантика заключается в разрыве связи имени).
Каждый оператор присваивания или импорта выполняется в блоке, определённом оператором определения класса или функции, или на уровне модуля (блок кода верхнего уровня).
Если имя привязано в блоке, то это локальная переменная этого блока, если не объявлена как nonlocal или global. Если имя привязано на уровне модуля, то это глобальная переменная. (Переменные блока кода модуля являются локальными и глобальными.) Если переменная используется в блоке кода, но не определена там, то это свободная переменная.
Каждое вхождение имени в тексте программы относится к привязке этого имени, установленной следующими правилами разрешения имён.
4.2.2. Разрешение имён
Область видимости определяет видимость имени в блоке. Если локальная переменная определена в блоке, её область видимости включает этот блок. Если определение происходит в блоке функции, область видимости распространяется на любые блоки, содержащиеся внутри определяющего блока, если содержащий блок не вводит другую привязку для имени.
Когда имя используется в блоке кода, оно разрешается с использованием ближайшей окружающей области видимости. Набор всех таких областей видимости, видимых для блока кода, называется средой блока.
Если имя вообще не найдено, возникает исключение NameError. Если текущая область видимости — это область видимости функции, и имя относится к локальной переменной, которая ещё не привязана к значению в точке использования имени, возникает исключение UnboundLocalError. UnboundLocalError является подклассом NameError.
Если операция привязки имени происходит где-либо в блоке кода, все использования имени в блоке обрабатываются как ссылки на текущий блок. Это может привести к ошибкам, когда имя используется в блоке до его привязки. Это правило тонкое. Python не имеет объявлений и позволяет операциям привязки имени происходить где угодно в блоке кода. Локальные переменные блока кода могут быть определены путём сканирования всего текста блока в поисках операций привязки имён. См. запись в FAQ об UnboundLocalError для примеров.
Если оператор global встречается в блоке, все использования имен, указанных в операторе, относятся к привязкам этих имён в пространстве имён верхнего уровня. Имена разрешаются в пространстве имён верхнего уровня путём поиска в глобальном пространстве имён, т. е. в пространстве имён модуля, содержащего блок кода, и в пространстве имён builtins, пространстве имён модуля builtins. Сначала ищется глобальное пространство имён. Если имена там не найдены, ищется пространство имён builtins. Оператор global должен предшествовать всем использованиям перечисленных имён.
Оператор global имеет такую же область видимости, как и операция привязки имени в том же блоке. Если ближайшая окружающая область видимости для свободной переменной содержит оператор global, то свободная переменная обрабатывается как глобальная.
Оператор nonlocal заставляет соответствующие имена ссылаться на ранее привязанные переменные в ближайшей окружающей области видимости функции. SyntaxError возбуждается во время компиляции, если указанное имя не существует ни в одной окружающей области видимости функции.
Пространство имён для модуля автоматически создаётся при первом импорте модуля. Главный модуль для скрипта всегда называется __main__.
Блоки определения классов и аргументы функций exec() и eval() являются специальными в контексте разрешения имён. Определение класса — это исполняемый оператор, который может использовать и определять имена. Эти ссылки следуют обычным правилам разрешения имён с исключением, что не привязанные локальные переменные ищутся в глобальном пространстве имён. Пространство имён определения класса становится словарем атрибутов класса. Область видимости имён, определённых в блоке класса, ограничена этим блоком; она не распространяется на блоки кода методов — это включает в себя генераторы и выражения генераторов, поскольку они реализованы с использованием области видимости функции. Это означает, что следующее не сработает:
class A:
a = 42
b = list(a + i for i in range(10))
4.2.3. Встроенные функции и ограниченное выполнение
Подробность реализации CPython: Пользователи не должны изменять __builtins__; это строго деталь реализации. Пользователи, которые хотят переопределить значения в пространстве имён builtins, должны import модуль builtins и соответствующим образом изменить его атрибуты.
Пространство имён builtins, связанное с выполнением блока кода, фактически находится путём поиска имени __builtins__ в его глобальном пространстве имён; это должен быть словарь или модуль (в последнем случае используется словарь модуля). По умолчанию, когда находится в модуле __main__, __builtins__ является встроенным модулем builtins; когда находится в любом другом модуле, __builtins__ является псевдонимом для словаря модуля builtins самому.
4.2.4. Взаимодействие с динамическими функциями
Разрешение имён свободных переменных происходит во время выполнения, а не во время компиляции. Это означает, что следующий код выведет 42:
i = 10
def f():
print(i)
i = 42
f()
Функции eval() и exec() не имеют доступа ко всей среде для разрешения имён. Имена могут быть разрешены в локальном и глобальном пространствах имён вызывающей стороны. Свободные переменные не разрешаются в ближайшей окружающей области видимости, а в глобальном пространстве имён. 1 Функции exec() и eval() имеют необязательные аргументы для переопределения глобального и локального пространств имён. Если указано только одно пространство имён, оно используется для обоих.
4.3. Исключения
Исключения — это способ выхода из обычного потока управления блоком кода для обработки ошибок или других исключительных ситуаций. Исключение возникает в месте обнаружения ошибки; оно может быть обработано окружающим блоком кода или любым блоком кода, непосредственно или косвенно вызвавшим блок кода, в котором произошла ошибка.
Интерпретатор Python поднимает исключение, когда обнаруживает ошибку во время выполнения (например, деление на ноль). Программа Python также может явно вызвать исключение с помощью инструкции raise. Обработчики исключений задаются с помощью инструкции try … except. Блок finally такой инструкции может использоваться для указания кода очистки, который не обрабатывает исключение, но выполняется независимо от того, возникло исключение или нет в предшествующем коде.
Python использует модель «прекращения» обработки ошибок: обработчик исключений может узнать, что произошло, и продолжить выполнение на внешнем уровне, но он не может исправить причину ошибки и повторить неудачную операцию (кроме повторного входа в проблемный фрагмент кода сверху).
Если исключение вообще не обрабатывается, интерпретатор прекращает выполнение программы или возвращается к своему интерактивному главному циклу. В обоих случаях он выводит трассировку стека, за исключением случаев, когда исключение является SystemExit.
Исключения идентифицируются экземплярами классов. Блок except выбирается в зависимости от класса экземпляра: он должен ссылаться на класс экземпляра или базовый класс (не виртуальный) от него. Экземпляр может быть получен обработчиком и может содержать дополнительную информацию об исключительном состоянии.
Примечание
Сообщения об исключениях не являются частью API Python. Их содержимое может меняться от одной версии Python к другой без предупреждения и не должно использоваться кодом, который будет работать под несколькими версиями интерпретатора.
См. также описание инструкции try в разделе Инструкция try и инструкции raise в разделе Инструкция raise.
Примечания
-
1 -
Это ограничение возникает, потому что код, выполняемый этими операциями, недоступен на момент компиляции модуля.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/reference/executionmodel.html