4. Модель исполнения¶
4.1. Структура программы¶
Программа на Python состоит из блоков кода. block - это фрагмент текста программы на Python, который выполняется как единое целое. Ниже приведены блоки: модуль, тело функции и определение класса. Каждая команда, вводимая в интерактивном режиме, представляет собой блок. Файл сценария (файл, предоставляемый интерпретатору в качестве стандартного ввода или указанный в качестве аргумента командной строки интерпретатора) представляет собой блок кода. Команда сценария (команда, указанная в командной строке интерпретатора с параметром -c
) представляет собой блок кода. Модуль, запускаемый как скрипт верхнего уровня (как модуль __main__
) из командной строки с использованием аргумента -m
, также является блоком кода. Строковый аргумент, передаваемый встроенным функциям eval()
и exec()
, представляет собой блок кода.
Блок кода выполняется в режиме execution frame. Фрейм содержит некоторую административную информацию (используемую для отладки) и определяет, где и как будет продолжено выполнение после завершения выполнения блока кода.
4.2. Присвоение имен и привязка¶
4.2.1. Привязка имен¶
Names относится к объектам. Имена вводятся с помощью операций привязки имен.
Следующие конструкции связывают имена:
формальные параметры для функций,
определения классов,
определения функций,
выражения присваивания,
targets, которые являются идентификаторами, если они встречаются в присваивании:
import
заявления.
Оператор import
вида from ... import *
связывает все имена, определенные в импортируемом модуле, за исключением тех, которые начинаются со знака подчеркивания. Эта форма может использоваться только на уровне модуля.
Целевой объект, встречающийся в инструкции del
, также считается привязанным для этой цели (хотя фактическая семантика заключается в том, чтобы отменить привязку имени).
Каждый оператор присваивания или импорта выполняется в блоке, определенном определением класса или функции, или на уровне модуля (блок кода верхнего уровня).
Если имя привязано к блоку, оно является локальной переменной этого блока, если только оно не объявлено как nonlocal
или global
. Если имя привязано на уровне модуля, это глобальная переменная. (Переменные блока кода модуля являются локальными и глобальными.) Если переменная используется в блоке кода, но не определена в нем, это free variable.
Каждое появление имени в тексте программы относится к binding этого имени, установленному следующими правилами разрешения имен.
4.2.2. Разрешение имен¶
scope определяет видимость имени внутри блока. Если в блоке определена локальная переменная, ее область действия включает этот блок. Если определение встречается в функциональном блоке, область действия распространяется на любые блоки, содержащиеся в определяющем, если только содержащийся в нем блок не вводит другую привязку для имени.
Когда в блоке кода используется имя, оно разрешается с использованием ближайшей охватывающей области. Совокупность всех таких областей, видимых для блока кода, называется environment блока.
Когда имя вообще не найдено, возникает исключение NameError
. Если текущая область является областью функции, а имя ссылается на локальную переменную, которая еще не была привязана к значению в момент использования имени, возникает исключение UnboundLocalError
. UnboundLocalError
является подклассом NameError
.
Если операция привязки имени выполняется в любом месте блока кода, все случаи использования имени в блоке рассматриваются как ссылки на текущий блок. Это может привести к ошибкам, если имя используется в блоке до его привязки. Это правило является тонким. В Python отсутствуют объявления, и операции привязки имен могут выполняться в любом месте внутри блока кода. Локальные переменные блока кода могут быть определены путем сканирования всего текста блока на предмет операций привязки имен. Примеры приведены в the FAQ entry on UnboundLocalError.
Если оператор global
встречается внутри блока, все варианты использования имен, указанных в этом операторе, относятся к привязкам этих имен в пространстве имен верхнего уровня. Имена разрешаются в пространстве имен верхнего уровня путем поиска в глобальном пространстве имен, т.е. в пространстве имен модуля, содержащего блок кода, и в пространстве имен builtins, пространстве имен модуля builtins
. Сначала выполняется поиск в глобальном пространстве имен. Если имена там не найдены, выполняется поиск в пространстве имен builtins. Оператор global
должен предшествовать всем использованиям перечисленных имен.
Оператор global
имеет ту же область действия, что и операция привязки имени, в том же блоке. Если ближайшая область действия для свободной переменной содержит глобальный оператор, свободная переменная рассматривается как глобальная.
Оператор nonlocal
приводит к тому, что соответствующие имена ссылаются на ранее привязанные переменные в ближайшей области охватывающей функции. SyntaxError
вызывается во время компиляции, если заданное имя не существует ни в одной области охватывающей функции.
Пространство имен для модуля создается автоматически при первом импорте модуля. Основной модуль для скрипта всегда называется __main__
.
Блоки определения класса и аргументы для exec()
и eval()
являются особыми в контексте разрешения имен. Определение класса - это исполняемая инструкция, которая может использовать и определять имена. Эти ссылки соответствуют обычным правилам разрешения имен, за исключением того, что поиск несвязанных локальных переменных выполняется в глобальном пространстве имен. Пространство имен определения класса становится словарем атрибутов класса. Область имен, определенных в блоке class, ограничивается блоком class; это не распространяется на блоки кода методов - это включает в себя описания и генераторные выражения, поскольку они реализованы с использованием области действия функции. Это означает, что следующее не удастся выполнить:
class A:
a = 42
b = list(a + i for i in range(10))
4.2.3. Здания и ограниченное исполнение¶
Детали реализации CPython: Пользователи не должны касаться __builtins__
; это строго относится к деталям реализации. Пользователи, желающие переопределить значения в пространстве имен builtins, должны import
модуль 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
выбирается в зависимости от класса экземпляра: оно должно ссылаться на класс экземпляра или на его non-virtual base class. Экземпляр может быть получен обработчиком и может содержать дополнительную информацию об исключительном состоянии.
Примечание
Сообщения об исключениях не являются частью API Python. Их содержимое может меняться от одной версии Python к другой без предупреждения, и на них не следует полагаться в коде, который будет выполняться в нескольких версиях интерпретатора.
Смотрите также описание инструкции try
в разделе Оператор try и инструкции raise
в разделе Оператор raise.
Сноски