Модель выполнения
4.1. Структура программы
Программа Python состоит из блоков кода. Блок — это фрагмент текста программы Python, выполняемый как единица. К блокам относятся: модуль, тело функции и определение класса. Каждая команда, введённая интерактивно, является блоком. Файл скрипта (файл, переданный в качестве стандартного входного потока интерпретатору или указанный в качестве аргумента командной строки интерпретатору) — это блок кода. Команда скрипта (команда, указанная в командной строке интерпретатора с опцией -c) — это блок кода. Модуль, запущенный как скрипт верхнего уровня (как модуль __main__) из командной строки с аргументом -m, также является блоком кода. Строковый аргумент, передаваемый встроенным функциям eval() и exec(), является блоком кода.
Блок кода выполняется в кадре выполнения. Кадр содержит некоторую административную информацию (используемую для отладки) и определяет, где и как продолжается выполнение после завершения выполнения блока кода.
4.2. Имена и привязка
4.2.1. Привязка имён
Имена ссылаются на объекты. Имена вводятся операциями привязки имён.
Следующие конструкции привязывают имена: формальные параметры функций, операторы import, определения классов и функций (они привязывают имя класса или функции в определяющем блоке) и целевые объекты, которые являются идентификаторами, если они встречаются в операторе присваивания, заголовке цикла for или после as в операторе with или блоке except. Оператор import вида from ... import * привязывает все имена, определённые в импортированном модуле, за исключением тех, которые начинаются с нижнего подчёркивания. Этот вид оператора может использоваться только на уровне модуля.
Целевой объект, встречающийся в операторе del, также считается привязанным для этой цели (хотя фактическая семантика заключается в разрыве привязки имени).
Каждый оператор присваивания или импорта находится внутри блока, определённого определением класса или функции, или на уровне модуля (блок кода верхнего уровня).
Если имя привязано в блоке, это локальная переменная этого блока, если не объявлено как nonlocal или global. Если имя привязано на уровне модуля, это глобальная переменная. (Переменные блока кода модуля являются локальными и глобальными.) Если переменная используется в блоке кода, но не определена в нём, это свободная переменная.
Каждое вхождение имени в тексте программы относится к привязке этого имени, установленной следующими правилами разрешения имён.
4.2.2. Разрешение имён
Область видимости определяет видимость имени в блоке. Если локальная переменная определена в блоке, её область видимости включает этот блок. Если определение происходит в блоке функции, область видимости распространяется на любые вложенные блоки, если вложенный блок не вводит другое привязывание для имени.
При использовании имени в блоке кода оно разрешается с использованием ближайшей внешней области видимости. Набор всех таких областей видимости, видимых блоком кода, называется окружением блока.
Если имя вообще не найдено, возникает исключение NameError. Если текущая область видимости — область видимости функции, и имя относится к локальной переменной, которая ещё не привязана к значению в точке использования имени, возникает исключение UnboundLocalError. UnboundLocalError является подклассом NameError.
Если операция привязки имени происходит где-либо в блоке кода, все использования имени внутри блока обрабатываются как ссылки на текущий блок. Это может привести к ошибкам, когда имя используется внутри блока до его привязки. Это правило тонкое. В Python нет объявлений, и операции привязки имён могут происходить где угодно в блоке кода. Локальные переменные блока кода могут быть определены путём сканирования всего текста блока на предмет операций привязки имён.
Если оператор 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–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/reference/executionmodel.html