executionmodel.md · Markdown – Документация Python
Документация Python неофициальный перевод

executionmodel.md

182 строк · 29.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.12/reference/executionmodel.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 4. Модель выполнения89## 4.1. Структура программы1011Программа на Python состоит из блоков кода. *Блок* – это фрагмент текста программы на Python, который выполняется как единое целое. Блоками являются: модуль, тело функции и определение класса. Каждая команда, введённая в интерактивном режиме, является блоком. Скриптовый файл (файл, передаваемый на стандартный ввод интерпретатора или указанный в качестве аргумента командной строки интерпретатора) является блоком кода. Скриптовая команда (команда, заданная в командной строке интерпретатора с опцией [`-c`](https://python-all.ru/3.12/using/cmdline.html#cmdoption-c)) является блоком кода. Модуль, запущенный как скрипт верхнего уровня (как модуль `__main__`) из командной строки с аргументом [`-m`](https://python-all.ru/3.12/using/cmdline.html#cmdoption-m), также является блоком кода. Строковый аргумент, переданный встроенным функциям [`eval()`](https://python-all.ru/3.12/library/functions.html#eval) и [`exec()`](https://python-all.ru/3.12/library/functions.html#exec), является блоком кода.1213Блок кода выполняется в *фрейме выполнения*. Фрейм содержит некоторую служебную информацию (используемую для отладки) и определяет, где и как продолжится выполнение после завершения выполнения блока кода.1415## 4.2. Именование и связывание1617### 4.2.1. Связывание имён1819*Имена* ссылаются на объекты. Имена вводятся операциями связывания имён.2021Следующие конструкции связывают имена:2223- формальные параметры функций,24- определения классов,25- определения функций,26- выражения присваивания,27- [targets](https://python-all.ru/3.12/reference/simple_stmts.html#assignment) that are identifiers if occurring in an assignment:2829  - заголовок цикла [`for`](https://python-all.ru/3.12/reference/compound_stmts.html#for),30  - после `as` в операторе [`with`](https://python-all.ru/3.12/reference/compound_stmts.html#with), в предложении [`except`](https://python-all.ru/3.12/reference/compound_stmts.html#except), предложении [`except*`](https://python-all.ru/3.12/reference/compound_stmts.html#except-star) или в as-шаблоне структурного сопоставления с образцом,31  - в шаблоне захвата структурного сопоставления с образцом,32- операторы [`import`](https://python-all.ru/3.12/reference/simple_stmts.html#import).33- операторы [`type`](https://python-all.ru/3.12/reference/simple_stmts.html#type).34- [type parameter lists](https://python-all.ru/3.12/reference/compound_stmts.html#type-params).3536Оператор `import` вида `from ... import *` связывает все имена, определённые в импортированном модуле, кроме тех, что начинаются с подчёркивания. Эта форма может использоваться только на уровне модуля.3738Цель, встречающаяся в операторе [`del`](https://python-all.ru/3.12/reference/simple_stmts.html#del), также считается связанной для данной цели (хотя фактическая семантика заключается в отмене связывания имени).3940Каждый оператор присваивания или импорта находится внутри блока, определённого классом или определением функции, либо на уровне модуля (блок кода верхнего уровня).4142Если имя связано в блоке, оно является локальной переменной этого блока, если только не объявлено как [`nonlocal`](https://python-all.ru/3.12/reference/simple_stmts.html#nonlocal) или [`global`](https://python-all.ru/3.12/reference/simple_stmts.html#global). Если имя связано на уровне модуля, оно является глобальной переменной. (Переменные блока кода модуля являются локальными и глобальными.) Если переменная используется в блоке кода, но не определена в нём, она является *свободной переменной*.4344Каждое вхождение имени в тексте программы ссылается на *связывание* этого имени, установленное следующими правилами разрешения имён.4546### 4.2.2. Разрешение имён4748*Область видимости* определяет видимость имени внутри блока. Если локальная переменная определена в блоке, её область видимости включает этот блок. Если определение находится в функциональном блоке, область видимости распространяется на любые блоки, вложенные в определяющий, если вложенный блок не вводит другое связывание для этого имени.4950Когда имя используется в блоке кода, оно разрешается с помощью ближайшей объемлющей области видимости. Множество всех таких областей, видимых блоку кода, называется его *окружением*.5152Когда имя не найдено вовсе, возбуждается исключение [`NameError`](https://python-all.ru/3.12/library/exceptions.html#NameError). Если текущая область видимости – функция, и имя ссылается на локальную переменную, которая ещё не привязана к значению в точке использования, возбуждается исключение [`UnboundLocalError`](https://python-all.ru/3.12/library/exceptions.html#UnboundLocalError). [`UnboundLocalError`](https://python-all.ru/3.12/library/exceptions.html#UnboundLocalError) является подклассом [`NameError`](https://python-all.ru/3.12/library/exceptions.html#NameError).5354Если операция связывания имени встречается в любом месте блока кода, все использования этого имени в блоке считаются ссылками на текущий блок. Это может приводить к ошибкам, когда имя используется в блоке до его связывания. Правило это тонкое. В Python нет объявлений, и операции связывания имени могут встречаться в любом месте блока кода. Локальные переменные блока кода можно определить, просмотрев весь текст блока на предмет операций связывания имён. Примеры см. в [FAQ про UnboundLocalError](https://python-all.ru/3.12/faq/programming.html#faq-unboundlocalerror).5556Если оператор [`global`](https://python-all.ru/3.12/reference/simple_stmts.html#global) встречается в блоке, все использования имён, указанных в операторе, ссылаются на привязки этих имён в пространстве имён верхнего уровня. Разрешение имён в пространстве имён верхнего уровня выполняется поиском в глобальном пространстве имён (т.е. пространстве имён модуля, содержащего блок кода) и в пространстве имён встроенных объектов (пространстве имён модуля [`builtins`](https://python-all.ru/3.12/library/builtins.html#module-builtins)). Сначала ищется глобальное пространство имён. Если имена не найдены там, затем ищется пространство имён встроенных объектов. Если имена не найдены и там, в глобальном пространстве имён создаются новые переменные. Оператор global должен предшествовать всем использованиям перечисленных имён.5758Оператор [`global`](https://python-all.ru/3.12/reference/simple_stmts.html#global) имеет ту же область видимости, что и операция связывания имени в том же блоке. Если ближайшая охватывающая область видимости для свободной переменной содержит оператор global, свободная переменная считается глобальной.5960Оператор [`nonlocal`](https://python-all.ru/3.12/reference/simple_stmts.html#nonlocal) заставляет соответствующие имена ссылаться на ранее связанные переменные в ближайшей охватывающей области видимости функции. [`SyntaxError`](https://python-all.ru/3.12/library/exceptions.html#SyntaxError) возбуждается на этапе компиляции, если указанное имя не существует ни в одной охватывающей функции. [Параметры типа](https://python-all.ru/3.12/reference/compound_stmts.html#type-params) нельзя перепривязать с помощью оператора `nonlocal`.6162Пространство имён модуля автоматически создаётся при первом импорте модуля. Главный модуль скрипта всегда называется [`__main__`](https://python-all.ru/3.12/library/__main__.html#module-__main__).6364Блоки определения класса и аргументы [`exec()`](https://python-all.ru/3.12/library/functions.html#exec) и [`eval()`](https://python-all.ru/3.12/library/functions.html#eval) являются особыми в контексте разрешения имён. Определение класса – это исполняемый оператор, который может использовать и определять имена. Эти ссылки следуют обычным правилам разрешения имён, за исключением того, что несвязанные локальные переменные ищутся в глобальном пространстве имён. Пространство имён определения класса становится словарём атрибутов класса. Область видимости имён, определённых в блоке класса, ограничена блоком класса; она не распространяется на блоки кода методов. Это включает генераторы списков и выражения генераторов, но не включает [области видимости аннотаций](https://python-all.ru/3.12/reference/executionmodel.html#annotation-scopes), которые имеют доступ к охватывающим областям видимости классов. Это означает, что следующий код не сработает:6566```python67class A:68    a = 4269    b = list(a + i for i in range(10))70```7172Однако следующий код сработает:7374```python75class A:76    type Alias = Nested77    class Nested: pass7879print(A.Alias.__value__)  # <type 'A.Nested'>80```8182### 4.2.3. Области видимости аннотаций8384[Списки параметров типа](https://python-all.ru/3.12/reference/compound_stmts.html#type-params) и [`type`](https://python-all.ru/3.12/reference/simple_stmts.html#type) инструкции вводят *области видимости аннотаций*, которые в основном ведут себя как области видимости функций, но с некоторыми исключениями, обсуждаемыми ниже. [Аннотации](https://python-all.ru/3.12/glossary.html#term-annotation) в настоящее время не используют области видимости аннотаций, но ожидается, что они будут использовать области видимости аннотаций в Python 3.13, когда будет реализован [**PEP 649**](https://python-all.ru/3.12/reference/executionmodel.html).8586Области видимости аннотаций используются в следующих контекстах:8788- Списки параметров типа для [обобщённых псевдонимов типов](https://python-all.ru/3.12/reference/compound_stmts.html#generic-type-aliases).89- Списки параметров типа для [обобщённых функций](https://python-all.ru/3.12/reference/compound_stmts.html#generic-functions). Аннотации обобщённой функции выполняются в области видимости аннотаций, но её значения по умолчанию и декораторы – нет.90- Списки параметров типа для [обобщённых классов](https://python-all.ru/3.12/reference/compound_stmts.html#generic-classes). Базовые классы и именованные аргументы обобщённого класса выполняются в области видимости аннотаций, но его декораторы – нет.91- Границы и ограничения для переменных типов ([вычисляются лениво](https://python-all.ru/3.12/reference/executionmodel.html#lazy-evaluation)).92- Значение псевдонимов типов ([лениво вычисляемое](https://python-all.ru/3.12/reference/executionmodel.html#lazy-evaluation)).9394Области видимости аннотаций отличаются от областей видимости функций следующим образом:9596- Области видимости аннотаций имеют доступ к пространству имён охватывающего класса. Если область видимости аннотаций находится непосредственно внутри области видимости класса или внутри другой области видимости аннотаций, которая находится непосредственно внутри области видимости класса, код в области видимости аннотаций может использовать имена, определённые в области видимости класса, как если бы он выполнялся непосредственно в теле класса. Это отличается от обычных функций, определённых внутри классов, которые не могут обращаться к именам, определённым в области видимости класса.97- Выражения в областях видимости аннотаций не могут содержать выражения [`yield`](https://python-all.ru/3.12/reference/simple_stmts.html#yield), `yield from`, [`await`](https://python-all.ru/3.12/reference/expressions.html#await) или [`:=`](https://python-all.ru/3.12/reference/expressions.html#grammar-token-python-grammar-assignment_expression). (Эти выражения разрешены в других областях видимости, вложенных в область видимости аннотаций.)98- Имена, определённые в областях видимости аннотаций, не могут быть перепривязаны с помощью операторов [`nonlocal`](https://python-all.ru/3.12/reference/simple_stmts.html#nonlocal) во вложенных областях. Это касается только параметров типа, так как никакие другие синтаксические элементы, которые могут встречаться в областях видимости аннотаций, не могут вводить новые имена.99- Хотя области видимости аннотаций имеют внутреннее имя, это имя не отражается в [квалифицированном имени](https://python-all.ru/3.12/glossary.html#term-qualified-name) объектов, определённых внутри области. Вместо этого [`__qualname__`](https://python-all.ru/3.12/library/stdtypes.html#definition.__qualname__) таких объектов выглядит так, как если бы объект был определён в охватывающей области.100101Добавлено в версии 3.12: Области видимости аннотаций были введены в Python 3.12 в рамках [**PEP 695**](https://python-all.ru/3.12/reference/executionmodel.html).102103### 4.2.4. Ленивое вычисление104105Значения псевдонимов типов, созданных с помощью оператора [`type`](https://python-all.ru/3.12/reference/simple_stmts.html#type), *вычисляются лениво*. То же самое относится к границам и ограничениям переменных типов, созданных через [синтаксис параметров типа](https://python-all.ru/3.12/reference/compound_stmts.html#type-params). Это означает, что они не вычисляются при создании псевдонима типа или переменной типа. Вместо этого они вычисляются только тогда, когда это необходимо для разрешения доступа к атрибуту.106107Пример:108109```pycon110>>> type Alias = 1/0111>>> Alias.__value__112Traceback (most recent call last):113  ...114ZeroDivisionError: division by zero115>>> def func[T: 1/0](): pass116>>> T = func.__type_params__[0]117>>> T.__bound__118Traceback (most recent call last):119  ...120ZeroDivisionError: division by zero121```122123Здесь исключение возбуждается только при обращении к атрибуту `__value__` псевдонима типа или атрибуту `__bound__` переменной типа.124125Такое поведение в первую очередь полезно для ссылок на типы, которые ещё не были определены на момент создания псевдонима типа или переменной типа. Например, ленивое вычисление позволяет создавать взаимно рекурсивные псевдонимы типов:126127```python128from typing import Literal129130type SimpleExpr = int | Parenthesized131type Parenthesized = tuple[Literal["("], Expr, Literal[")"]]132type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], Expr]133```134135Лениво вычисляемые значения вычисляются в [области видимости аннотаций](https://python-all.ru/3.12/reference/executionmodel.html#annotation-scopes), что означает, что имена, встречающиеся внутри лениво вычисляемого значения, ищутся так, как если бы они использовались в непосредственно охватывающей области.136137Добавлено в версии 3.12.138139### 4.2.5. Встроенные объекты и ограниченное выполнение140141**Деталь реализации CPython:** Пользователям не следует трогать `__builtins__`; это строго деталь реализации. Пользователи, желающие переопределить значения в пространстве имён builtins, должны [`import`](https://python-all.ru/3.12/reference/simple_stmts.html#import) модуль [`builtins`](https://python-all.ru/3.12/library/builtins.html#module-builtins) и соответствующим образом изменить его атрибуты.142143Пространство имён builtins, связанное с выполнением блока кода, на самом деле находится путём поиска имени `__builtins__` в его глобальном пространстве имён; это должен быть словарь или модуль (в последнем случае используется словарь модуля). По умолчанию, в модуле [`__main__`](https://python-all.ru/3.12/library/__main__.html#module-__main__) `__builtins__` является встроенным модулем [`builtins`](https://python-all.ru/3.12/library/builtins.html#module-builtins); во всех остальных модулях `__builtins__` является псевдонимом для словаря самого модуля [`builtins`](https://python-all.ru/3.12/library/builtins.html#module-builtins).144145### 4.2.6. Взаимодействие с динамическими возможностями146147Разрешение имён свободных переменных происходит во время выполнения, а не во время компиляции. Это означает, что следующий код выведет 42:148149```python150i = 10151def f():152    print(i)153i = 42154f()155```156157Функции [`eval()`](https://python-all.ru/3.12/library/functions.html#eval) и [`exec()`](https://python-all.ru/3.12/library/functions.html#exec) не имеют доступа к полному окружению для разрешения имён. Имена могут разрешаться в локальном и глобальном пространствах имён вызывающего кода. Свободные переменные разрешаются не в ближайшем охватывающем пространстве имён, а в глобальном. [\[1\]](https://python-all.ru/3.12/reference/executionmodel.html#id5) Функции [`exec()`](https://python-all.ru/3.12/library/functions.html#exec) и [`eval()`](https://python-all.ru/3.12/library/functions.html#eval) имеют необязательные аргументы для переопределения глобального и локального пространства имён. Если указано только одно пространство имён, оно используется для обоих.158159## 4.3. Исключения160161Исключения – это средство выхода из нормального потока управления блока кода для обработки ошибок или других исключительных ситуаций. Исключение *возбуждается* в том месте, где обнаружена ошибка; оно может быть *обработано* окружающим блоком кода или любым блоком кода, который прямо или косвенно вызвал блок кода, в котором произошла ошибка.162163Интерпретатор Python возбуждает исключение, когда обнаруживает ошибку времени выполнения (например, деление на ноль). Программа на Python также может явно возбудить исключение с помощью оператора [`raise`](https://python-all.ru/3.12/reference/simple_stmts.html#raise). Обработчики исключений задаются с помощью оператора [`try`](https://python-all.ru/3.12/reference/compound_stmts.html#try) … [`except`](https://python-all.ru/3.12/reference/compound_stmts.html#except). Предложение [`finally`](https://python-all.ru/3.12/reference/compound_stmts.html#finally) такого оператора можно использовать для указания кода очистки, который не обрабатывает исключение, но выполняется независимо от того, было ли исключение в предшествующем коде.164165В Python используется модель обработки ошибок с «завершением»: обработчик исключений может выяснить, что произошло, и продолжить выполнение на внешнем уровне, но он не может исправить причину ошибки и повторить сбойную операцию (кроме случая повторного входа в проблемный кусок кода с самого начала).166167Если исключение вообще не обрабатывается, интерпретатор завершает выполнение программы или возвращается в свой основной интерактивный цикл. В любом случае выводится трассировка стека, за исключением случая, когда исключение – [`SystemExit`](https://python-all.ru/3.12/library/exceptions.html#SystemExit).168169Исключения идентифицируются экземплярами классов. Предложение [`except`](https://python-all.ru/3.12/reference/compound_stmts.html#except) выбирается в зависимости от класса экземпляра: оно должно ссылаться на класс экземпляра или на его [невиртуальный базовый класс](https://python-all.ru/3.12/glossary.html#term-abstract-base-class). Экземпляр может быть получен обработчиком и может нести дополнительную информацию об исключительной ситуации.170171> **Примечание**172>173> Сообщения исключений не являются частью API Python. Их содержимое может меняться от одной версии Python к другой без предупреждения, и на него не следует полагаться в коде, который будет выполняться под несколькими версиями интерпретатора.174175См. также описание оператора [`try`](https://python-all.ru/3.12/reference/compound_stmts.html#try) в разделе [Оператор try](https://python-all.ru/3.12/reference/compound_stmts.html#try) и оператора [`raise`](https://python-all.ru/3.12/reference/simple_stmts.html#raise) в разделе [Оператор raise](https://python-all.ru/3.12/reference/simple_stmts.html#raise).176177Сноски178179\[[1](https://python-all.ru/3.12/reference/executionmodel.html#id3)\]180181Это ограничение возникает потому, что код, который выполняется этими операциями, недоступен на момент компиляции модуля.182