# 7. Простые инструкции

Простая инструкция состоит из одной логической строки. Несколько простых инструкций могут находиться в одной строке, разделённой точкой с запятой. Синтаксис простых инструкций:

    simple_stmt: expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | annotated_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | future_stmt
                 | global_stmt
                 | nonlocal_stmt
                 | type_stmt

## 7.1. Инструкции выражений

Инструкции выражений используются (в основном в интерактивном режиме) для вычисления и вывода значения или (обычно) для вызова процедуры (функции, которая не возвращает значимого результата; в Python процедуры возвращают значение `None`). Другие варианты использования инструкций выражений разрешены и иногда полезны. Синтаксис инструкции выражения:

    expression_stmt: starred_expression

Инструкция выражения вычисляет список выражений (который может быть одним выражением).

В интерактивном режиме, если значение отличается от `None`, оно преобразуется в строку с помощью встроенной функции `repr()`, и результирующая строка записывается в стандартный вывод в отдельной строке (кроме случаев, когда результатом будет `None`, так что вызовы процедур не приводят к каким-либо выводам).

## 7.2. Инструкции присваивания

Инструкции присваивания используются для (повторного) связывания имён со значениями, а также для изменения атрибутов или элементов изменяемых объектов:

    assignment_stmt: (target_list "=")+ (starred_expression | yield_expression)
    target_list:     target ("," target)* [","]
    target:          identifier
                     | "(" [target_list] ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | "*" target

(См. раздел Primaries для описания синтаксиса обращения к атрибуту и обращения к элементу).

Инструкция присваивания вычисляет список выражений (напомним, что это может быть одно выражение или список выражений, разделённых запятыми; в последнем случае результатом является кортеж) и присваивает один получившийся объект каждому целевому списку слева направо.

Присваивание определяется рекурсивно в зависимости от формы цели (или целевого списка). Когда цель является частью изменяемого объекта (обращение к атрибуту или к элементу), сам этот объект должен в конечном итоге выполнить присваивание и принять решение о его допустимости, в противном случае может быть выброшено исключение. Правила, соблюдаемые различными типами, и возникающие исключения приведены вместе с определением типов объектов (см. раздел Иерархия стандартных типов).

Присваивание объекта целевому списку, при необходимости заключённому в круглые или квадратные скобки, определяется рекурсивно следующим образом.

- Если целевой список состоит из одной цели без завершающей запятой, возможно в круглых скобках, объект присваивается этой цели.

- Иначе:

  - Если целевой список содержит одну цель со звёздочкой в префиксе, называемую «звёздной» целью, то объект должен быть итерируемым. Число элементов в нём может быть больше, чем в целевом списке, равным ему или ровно на один меньше. Первые элементы итерируемого объекта присваиваются, слева направо, целям до звёздной, а последние — после неё. Затем оставшиеся элементы итерируемого объекта формируют список (возможно пустой), который присваивается самой звёздной цели.

  - Иначе: объект должен быть итерируемым и содержать столько же элементов, сколько и в целевом списке, и элементы присваиваются соответствующим целям, слева направо.

Присваивание объекта одной цели определяется рекурсивно следующим образом.

- Если целью является идентификатор (имя):

  - Если имя не встречается в инструкции `global` или `nonlocal` в текущем блоке кода, оно связывается с объектом в текущем локальном пространстве имён.

  - В противном случае имя связывается с объектом в глобальном пространстве имён или во внешнем, определяемом `nonlocal`, соответственно.

  Если имя уже было связано с каким-либо объектом, оно переназначается. Это может привести к тому, что счётчик ссылок на объект, ранее связанный с именем, достигнет нуля, что вызовет освобождение объекта и вызов его деструктора (если он определён).

- Если целью является ссылка на атрибут, сначала вычисляется первичное выражение в ссылке. Оно должно вернуть объект с присваиваемыми атрибутами; если это не так, возбуждается исключение `TypeError`. Затем у этого объекта запрашивается присваивание переданного объекта указанному атрибуту; если объект не может выполнить присваивание, выбрасывается исключение (обычно, но не обязательно, `AttributeError`).

  Примечание: если объект является экземпляром класса и ссылка на атрибут встречается с обеих сторон знака присваивания, выражение справа, например `a.x`, может обращаться либо к атрибуту экземпляра, либо (если атрибут экземпляра отсутствует) к атрибуту класса. Цель слева, `a.x`, всегда устанавливается как атрибут экземпляра, создавая его при необходимости. Таким образом, два вхождения `a.x` не обязательно ссылаются на один и тот же атрибут: если выражение справа ссылается на атрибут класса, левая часть создаёт новый атрибут экземпляра, который становится целью присваивания.

      class Cls:
          x = 3             # переменная класса
      inst = Cls()
      inst.x = inst.x + 1   # записывает 4 в inst.x, при этом Cls.x остаётся 3

  Это описание не обязательно применимо к дескрипторным атрибутам, таким как свойства, создаваемые с помощью `@property`.

- Если в качестве цели используется обращение к элементу, сначала вычисляется первичное выражение в этом обращении, затем — выражение индексатора. После этого вызывается метод `__setitem__()` первичного объекта с двумя аргументами: значением индексатора и присваиваемым объектом.

  Как правило, метод `__setitem__()` определён у изменяемых последовательностей (таких как списки) и отображений (таких как словари) и ведёт себя следующим образом.

  Если первичный объект является объектом изменяемой последовательности (например, списком), выражение индексатора должно возвращать целое число. Если оно отрицательное, к нему прибавляется длина последовательности. Полученное таким образом значение должно быть неотрицательным целым числом меньше длины последовательности. Затем последовательности поручается присвоить объект элементу с этим индексом. Если индекс выходит за пределы допустимого диапазона, выбрасывается исключение `IndexError` (присваивание элементу последовательности через индекс не может добавлять новые элементы в список).

  Если первичный объект является объектом отображения (например, словарём), выражение индексатора должно иметь тип, совместимый с типом ключей отображения. Затем отображению поручается создать пару ключ/значение, которая связывает индексатор с присваиваемым объектом. Это может либо заменить существующую пару с таким же ключом, либо вставить новую пару ключ/значение (если ключ с таким значением ранее отсутствовал).

  Если целью присваивания является срез, первичное выражение должно вычисляться в изменяемую последовательность (например, список). Присваиваемый объект должен быть итерируемым. Нижняя и верхняя границы среза должны быть целыми числами; если они равны `None` (или отсутствуют), по умолчанию используются ноль и длина последовательности. Если какая-либо из границ отрицательна, к ней прибавляется длина последовательности. Полученные границы затем ограничиваются диапазоном от нуля до длины последовательности включительно. Наконец, последовательности поручается заменить указанный срез элементами присваиваемой последовательности. Длина среза может отличаться от длины присваиваемой последовательности, что приводит к изменению длины целевой последовательности, если она это позволяет.

Хотя определение присваивания подразумевает, что пересечения между левой и правой частью происходят «одновременно» (например, `a, b = b, a` меняет значения двух переменных местами), пересечения внутри множества присваиваемых переменных выполняются слева направо, что иногда приводит к неожиданным результатам. Например, следующая программа выводит `[0, 2]`:

    x = [0, 1]
    i = 0
    i, x[i] = 1, 2         # сначала обновляется i, затем обновляется x[i]
    print(x)

См. также

PEP 3132 — Расширенная распаковка итерируемых объектов

  Спецификация конструкции `*target`.

### 7.2.1. Комбинированные инструкции присваивания

Комбинированное присваивание — это объединение в одной инструкции бинарной операции и инструкции присваивания:

    augmented_assignment_stmt: augtarget augop (expression_list | yield_expression)
    augtarget:                 identifier | attributeref | subscription
    augop:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

(См. раздел Primaries для описания синтаксиса трёх последних операторов.)

Комбинированная инструкция присваивания вычисляет целевой объект (который, в отличие от обычного присваивания, не может быть списком целей и учавствовать в распаковке) и список выражений, выполняет бинарную операцию, соответствующую типу присваивания, над двумя операндами и присваивает результат исходной цели. Цель присваивания вычисляется только один раз.

Инструкция вида `x += 1` может быть переписана как `x = x + 1` для получения похожего, но не полностью идентичного результата. В комбинированной инструкции присваивания `x` вычисляется только один раз. Кроме того, когда возможно, операция выполняется на месте, то есть вместо создания нового объекта и присваивания его цели, изменяется существующий объект.

В отличие от обычного присваивания, комбинированное присваивание вычисляет левую часть перед правой. Например, в выражении `a[i] += f(x)` сначала вычисляется `a[i]`, затем вычисляется `f(x)` и выполняется сложение, после чего результат записывается обратно в `a[i]`.

За исключением присваивания кортежам и множеству целей в одной инструкции, присваивание, выполняемое комбинированной инструкцией, обрабатывается так же, как обычное присваивание. Аналогично, за исключением возможного поведения на месте, бинарная операция, выполняемая при комбинированном присваивании, идентична обычной бинарной операции.

Для целей, которые являются ссылками на атрибуты, действует то же предостережение о различии атрибутов класса и экземпляра, что и для обычного присваивания.

### 7.2.2. Аннотированные инструкции присваивания

Аннотированное присваивание — это комбинация в одной инструкции аннотации переменной или атрибута с необязательной инструкцией присваивания:

    annotated_assignment_stmt: augtarget ":" expression
                               ["=" (starred_expression | yield_expression)]

Отличие от обычного Инструкции присваивания заключается в том, что допускается только одна цель.

Цель присваивания считается «простой», если она состоит из одного имени, не заключённого в скобки. Для простых целей в области видимости класса или модуля^ аннотации собираются в вычисляемую отложенно область аннотаций. Эти аннотации можно получить через атрибут `__annotations__` класса или модуля, либо через средства модуля `annotationlib`.

Если цель присваивания не является простой (то есть атрибутом, обращением к элементу или именем в скобках), аннотация никогда не вычисляется.

Если имя аннотировано в области видимости функции, оно считается локальным для этой области. Аннотации в функциях никогда не вычисляются и не сохраняются.

Если правая часть присутствует, аннотированное присваивание выполняет присваивание как обычное, игнорируя аннотацию. Если правая часть отсутствует, интерпретатор вычисляет выражение для цели, но не выполняет последующий вызов `__setitem__()` или `__setattr__()`.

См. также

PEP 526 — Синтаксис аннотаций переменных

  Предложение, добавившее синтаксис для указания типов переменных (включая переменные классов и экземпляров), вместо использования комментариев.

PEP 484 — Подсказки типов

  Предложение, добавившее модуль `typing` для стандартного синтаксиса аннотаций типов, который может использоваться инструментами статического анализа и IDE.

Изменено в версии 3.8: Теперь аннотированные присваивания допускают те же выражения в правой части, что и обычные присваивания. Ранее некоторые выражения (например, кортежи без скобок) вызывали синтаксическую ошибку.

Изменено в версии 3.14: Аннотации теперь вычисляются отложенно в отдельной области аннотаций. Если цель присваивания не является простой, аннотации никогда не вычисляются.

## 7.3. Инструкция `assert`

Инструкции assert — это удобный способ вставки отладочных утверждений в программу:

    assert_stmt: "assert" expression ["," expression]

Простая форма, `assert expression`, эквивалентна

    if __debug__:
        if not expression: raise AssertionError

Расширенная форма, `assert expression1, expression2`, эквивалентна

    if __debug__:
        if not expression1: raise AssertionError(expression2)

Этот эквивалентный код предполагает, что `__debug__` и `AssertionError` ссылаются на одноимённые встроенные переменные. В текущей реализации встроенная переменная `__debug__` имеет значение `True` при обычном запуске и `False`, когда запрошена оптимизация (опция командной строки `-O`). Текущий генератор кода не создаёт никакого кода для инструкции `assert`, если оптимизация запрошена во время компиляции. Обратите внимание, что нет необходимости включать исходный код выражения, которое не прошло проверку, в сообщение об ошибке; он будет отображён как часть трассировки стека.

Присваивания `__debug__` недопустимы. Значение этой встроенной переменной определяется при запуске интерпретатора.

## 7.4. Инструкция `pass`

    pass_stmt: "pass"

Инструкция `pass` — это пустая операция. При её выполнении ничего не происходит. Она полезна как заглушка в тех случаях, когда синтаксически требуется инструкция, но выполнять никакой код не нужно, например:

    def f(arg): pass    # функция, которая (пока) ничего не делает

    class C: pass       # класс без методов (пока)

## 7.5. Инструкция `del`

    del_stmt: "del" target_list

Удаление определяется рекурсивно, очень похоже на то, как определяется присваивание. Вместо подробного изложения всех деталей ниже приведены некоторые пояснения.

Удаление списка целей рекурсивно удаляет каждую цель слева направо.

Удаление имени удаляет привязку этого имени из локального или глобального пространства имён — в зависимости от того, присутствует ли это имя в инструкции `global` в том же блоке кода. Попытка удалить имя без привязки приводит к возбуждению исключения `NameError`.

Удаление атрибутов и элементов через индексирование передаётся соответствующему первичному объекту. Удаление среза в общем случае эквивалентно присваиванию пустого среза соответствующего типа (однако даже это определяется объектом, к которому применяется срез).

Изменено в версии 3.2: Раньше было запрещено удалять имя из локального пространства имён, если оно встречается как свободная переменная во вложенном блоке.

## 7.6. Инструкция `return`

    return_stmt: "return" [expression_list]

`return` может встречаться только внутри определения функции, но не внутри определения вложенного класса.

Если список выражений присутствует, он вычисляется, в противном случае он заменяется на `None`.

`return` завершает текущий вызов функции, возвращая список выражений (или `None`) в качестве значения.

Когда `return` выходит из инструкции `try` с `finally`, то перед фактическим завершением функции выполняется этот блок `finally`.

В генераторной функции инструкция `return` указывает на завершение генератора и выбрасывает исключение `StopIteration`. Возвращаемое значение (если есть) передаётся конструктору `StopIteration` и становится атрибутом `StopIteration.value`.

В асинхронной генераторной функции пустая инструкция `return` указывает на завершение генератора и выбрасывает `StopAsyncIteration`. Непустая инструкция `return` в асинхронной генераторной функции является синтаксической ошибкой.

## 7.7. Инструкция `yield`

    yield_stmt: yield_expression

Инструкция `yield` семантически эквивалентна выражению yield. Использование инструкции `yield` позволяет не ставить скобки, которые требовались бы в эквивалентном выражении yield. Например, инструкции

    yield <expr>
    yield from <expr>

эквивалентны выражениям

    (yield <expr>)
    (yield from <expr>)

Выражения и инструкции yield используются только при определении генераторной функции и только в её теле. Использование `yield` внутри определения функции делает эту функцию генераторной, а не обычной.

Полную информацию о семантике `yield` можно найти в разделе Yield expressions.

## 7.8. Инструкция `raise`

    raise_stmt: "raise" [expression ["from" expression]]

Если выражения отсутствуют, инструкция `raise` повторно возбуждает исключение, которое в данный момент обрабатывается, так называемое активное исключение. Если активного исключения нет, возбуждается исключение `RuntimeError`, указывающее на ошибку.

В противном случае `raise` вычисляет первое выражение как объект исключения. Оно должно быть либо подклассом `BaseException`, либо его экземпляром. Если указан класс, экземпляр исключения будет создан по мере необходимости путём вызова конструктора без аргументов.

Тип исключения — это класс экземпляра исключения, а значение — сам экземпляр.

Объект трассировки обычно создаётся автоматически при возбуждении исключения и присоединяется к нему в атрибуте `__traceback__`. Создать исключение и сразу задать собственную трассировку можно за один шаг с помощью метода `with_traceback()`, который возвращает тот же экземпляр исключения с установленным объектом трассировки, например:

    raise Exception("произошло foo").with_traceback(tracebackobj)

Часть `from` используется для построения цепочек исключений: если она указана, второе выражение должно быть другим классом исключения или его экземпляром. Если второе выражение — экземпляр исключения, он присоединяется к возбуждаемому исключению в атрибуте `__cause__` (доступном для записи). Если указан класс исключения, он будет инстанцирован, и полученный экземпляр будет присоединён к возбуждаемому исключению в атрибуте `__cause__`. Если исключение не перехватывается, выводятся оба исключения.

    >>> try:
    ...     print(1 / 0)
    ... except Exception as exc:
    ...     raise RuntimeError("Случилось что-то плохое") from exc
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
        print(1 / 0)
              ~~^~~
    ZeroDivisionError: division by zero

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
        raise RuntimeError("Случилось что-то плохое") from exc
    RuntimeError: Случилось что-то плохое

Похожий механизм работает неявно, если новое исключение возбуждается в момент, когда другое исключение уже обрабатывается. Исключение считается обрабатываемым внутри блоков `except` и `finally` или инструкции `with`. В этом случае предыдущее исключение присоединяется к новому в атрибуте `__context__`:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Случилось что-то плохое")
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
        print(1 / 0)
              ~~^~~
    ZeroDivisionError: division by zero

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
        raise RuntimeError("Случилось что-то плохое")
    RuntimeError: Случилось что-то плохое

Цепочку исключений можно явно подавить, указав `None` в части `from`:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Случилось что-то плохое") from None
    ...
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    RuntimeError: Случилось что-то плохое

Дополнительную информацию об исключениях можно найти в разделе Exceptions, а информацию об их обработке — в разделе The try statement.

Изменено в версии 3.3: Теперь `None` допускается в качестве `Y` в конструкции `raise X from Y`.

Добавлен атрибут `__suppress_context__` для подавления автоматического отображения контекста исключения.

Изменено в версии 3.11: Если трассировка активного исключения изменяется в блоке `except`, последующая инструкция `raise` повторно возбуждает исключение с изменённой трассировкой. Ранее исключение повторно возбуждалось с трассировкой, которая была у него в момент перехвата.

## 7.9. Инструкция `break`

    break_stmt: "break"

Инструкция `break` может использоваться только внутри циклов `for` или `while`, но не внутри определения функции или класса, вложенного в такой цикл.

Она завершает ближайший охватывающий цикл, пропуская необязательную часть `else`, если она у цикла есть.

Если цикл `for` завершается инструкцией `break`, управляющая переменная цикла сохраняет своё текущее значение.

Когда `break` передаёт управление за пределы инструкции `try` с частью `finally`, то перед фактическим выходом из цикла выполняется эта часть `finally`.

## 7.10. Инструкция `continue`

    continue_stmt: "continue"

Инструкция `continue` может использоваться только внутри циклов `for` или `while`, но не внутри определения функции или класса, вложенного в такой цикл. Она немедленно переходит к следующей итерации ближайшего охватывающего цикла.

Когда `continue` передаёт управление за пределы инструкции `try` с частью `finally`, то перед фактическим началом следующей итерации цикла выполняется эта часть `finally`.

## 7.11. Инструкция `import`

    import_stmt:     ["lazy"] "import" module ["as" identifier] ("," module ["as" identifier])*
                     | ["lazy"] "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | ["lazy"] "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" relative_module "import" "*"
    module:          (identifier ".")* identifier
    relative_module: "."* module | "."+

Базовая форма инструкции импорта (без части `from`) выполняется в два этапа:

1. находится модуль, который при необходимости загружается и инициализируется

2. определяет имя или имена в текущем пространстве имён для области видимости, в которой находится инструкция `import`, так же, как это делает инструкция присваивания (включая семантику `global` и `nonlocal`).

Когда инструкция содержит несколько частей (разделённых запятыми), эти два шага выполняются отдельно для каждой части, словно каждая из них была записана в виде отдельной инструкции импорта.

Подробности первого шага — поиска и загрузки модулей — описаны в разделе система импорта, который также рассматривает различные типы пакетов и модулей, которые могут быть импортированы, а также все хуки, с помощью которых можно настраивать систему импорта. Обратите внимание, что ошибки на этом этапе могут означать то, что модуль не удалось найти, либо что ошибка произошла при инициализации модуля, которая включает выполнение его кода.

Если запрошенный модуль успешно получен, он будет доступен в локальном пространстве имён одним из трёх способов:

- Если за именем модуля следует `as`, то имя после `as`, связывается непосредственно с импортированным модулем.

- Если другое имя не указано и импортируемый модуль является модулем верхнего уровня, имя модуля связывается в локальном пространстве имён как ссылка на импортированный модуль.

- Если импортируемый модуль не является модулем верхнего уровня, то имя пакета верхнего уровня, содержащего модуль, связывается в локальном пространстве имён как ссылка на этот пакет. Доступ к импортированному модулю должен осуществляться по его полному имени, а не напрямую.

Форма `from` использует немного более сложный процесс:

1. находится модуль, указанный в части `from`, при необходимости он загружается и инициализируется;

2. для каждого идентификатора, указанного в части `import`:

   1. проверяется, есть ли у импортированного модуля атрибут с этим именем

   2. если атрибут не найден, осуществляется попытка импортировать подмодуль с этим именем и снова проверить наличие атрибута в нём

   3. если атрибут всё ещё не найден, возбуждается исключение `ImportError`

   4. если атрибут найден, в текущем пространстве имён создаётся ссылка на это значение, используя имя из части `as`, если оно указано, иначе — имя атрибута

Примеры:

    import foo                 # модуль foo импортирован и связан локально
    import foo.bar.baz         # модули foo, foo.bar и foo.bar.baz импортированы, foo связано локально
    import foo.bar.baz as fbb  # модули foo, foo.bar и foo.bar.baz импортированы, foo.bar.baz связано как fbb
    from foo.bar import baz    # модули foo, foo.bar и foo.bar.baz импортированы, foo.bar.baz связано как baz
    from foo import attr       # модуль foo импортирован и foo.attr связано как attr

Если список идентификаторов заменён на звёздочку (`'*'`), все общедоступные имена, определённые в модуле, связываются в локальном пространстве имён той области видимости, где встречается инструкция `import`.

Общедоступные имена модуля определяются следующим образом: проверяется наличие переменной с именем `__all__` в пространстве имён модуля. Если она определена, это должна быть последовательность строк, каждая из которых является именем, определённым или импортированным этим модулем. Имена, содержащие символы, отличные от ASCII, должны находиться в нормализованной форме NFKC; подробности см. в Не-ASCII символы в именах. Все имена, указанные в `__all__`, считаются общедоступными и должны существовать. Если `__all__` не определено, публичными считаются все имена в пространстве имён модуля, которые не начинаются с символа подчёркивания (`'_'`). Переменная `__all__` должна включать весь публичный API модуля. Она предназначена для предотвращения случайного экспорта элементов, не являющихся частью его API (например, библиотечных модулей, импортированных и использованных внутри модуля).

Форма импорта с подстановочным знаком — `from module import *` — разрешена только на уровне модуля. Попытка использовать её внутри определения класса или функции приводит к возбуждению исключения `SyntaxError`.

При указании импортируемого модуля не обязательно задавать его абсолютное имя. Если модуль или пакет находится внутри другого пакета, можно выполнить относительный импорт в пределах того же верхнеуровневого пакета, не указывая его имя. Используя ведущие точки в имени модуля или пакета после ключевого слова `from`, можно указать, на сколько уровней вверх по иерархии пакетов следует подняться, не перечисляя точные имена. Одна ведущая точка означает текущий пакет, в котором находится модуль, выполняющий импорт. Две точки — подъём на один уровень вверх, три точки — на два уровня и так далее. Так, при выполнении `from . import mod` из модуля в пакете `pkg` будет импортирован `pkg.mod`. При выполнении `from ..subpkg2 import mod` из `pkg.subpkg1` будет импортирован `pkg.subpkg2.mod`. Спецификация относительных импортов приведена в разделе Package Relative Imports.

Функция `importlib.import_module()` предназначена для поддержки приложений, которые динамически определяют загружаемые модули.

Возбуждает событие аудита `import` с аргументами `module`, `filename`, `sys.path`, `sys.meta_path` и `sys.path_hooks`.

### 7.11.1. Ленивый импорт

Ключевое слово `lazy` является мягким ключевым словом, которое имеет специальное значение только тогда, когда оно находится непосредственно перед инструкцией `import` или `from`. Если перед инструкцией импорта находится ключевое слово `lazy`, импорт становится ленивым: модуль не загружается сразу в месте инструкции импорта. Вместо этого создаётся ленивый прокси-объект и привязывается к имени. Фактическая загрузка модуля происходит при первом использовании этого имени.

Ленивые импорты разрешены только на уровне модуля. Использование `lazy` внутри функции, тела класса или блока `try`/`except`/`finally` возбуждает исключение `SyntaxError`. Импорты с подстановочным знаком не могут быть ленивыми (`lazy from module import *` является синтаксической ошибкой) так же, как и инструкции будущих возможностей.

При использовании `lazy from ... import` каждое импортированное имя связывается с ленивым прокси-объектом. Первое обращение к любому из этих имён запускает загрузку всего модуля и разрешает только это конкретное имя, заменяя его фактическим значением. Остальные имена остаются ленивыми прокси-объектами до тех пор, пока к ним не обратятся.

Пример:

    lazy import json
    import sys

    print('json' in sys.modules)  # False — модуль json ещё не загружен

    # Первое использование запускает загрузку
    result = json.dumps({"привет": "мир"})

    print('json' in sys.modules)  # True — теперь загружен

Если во время загрузки модуля возникает ошибка (например, `ImportError` или `SyntaxError`), она возбуждается в месте первого использования ленивого импорта, а не в самой инструкции импорта.

См. PEP 810 для полной спецификации ленивых импортов.

Добавлено в версии 3.15.

#### 7.11.1.1. Совместимость через `__lazy_modules__`

В качестве альтернативы использованию ключевого слова `lazy` модуль может включить ленивую загрузку для определённых импортов, определив переменную уровня модуля `__lazy_modules__`. Если она присутствует, она должна быть контейнером строк с полными квалифицированными именами модулей. Любая обычная (без ключевого слова `lazy`) инструкция `import` на уровне модуля, цель которой содержится в `__lazy_modules__`, рассматривается как ленивый импорт — так же, как если бы использовалось ключевое слово `lazy`.

Это позволяет включить ленивую загрузку для определённых зависимостей, не изменяя отдельные инструкции `import`. Это позволяет поддерживать версии Python старше 3.15 и одновременно использовать ленивые импорты в Python 3.15 и более новых версиях.

    __lazy_modules__ = ["json", "pathlib"]

    import json     # загружается лениво (имя есть в __lazy_modules__)
    import os       # загружается сразу (имени нет в __lazy_modules__)

    import pathlib  # загружается лениво

Относительные импорты перед проверкой преобразуются в абсолютные имена, поэтому `__lazy_modules__` всегда должен содержать полные квалифицированные имена модулей.

Для `from`-style imports, the relevant name is the module following `from`, а не имена его элементов:

    # В mypackage/mymodule.py
    __lazy_modules__ = ["mypackage", "mypackage.sub.utils"]

    from . import helper         # загружается лениво: . разрешается в mypackage
    from .sub.utils import func  # загружается лениво: .sub.utils разрешается в mypackage.sub.utils
    import json                  # загружается сразу (нет в __lazy_modules__)

Импорты внутри функций, тел классов или блоков `try`/`except`/`finally` всегда выполняются сразу, независимо от `__lazy_modules__`.

Добавлено в версии 3.15.

### 7.11.2. Инструкции будущих возможностей

Инструкция будущих возможностей — это директива компилятору, указывающая, что данный модуль должен компилироваться с использованием синтаксиса или семантики, которые станут стандартными в одном из будущих выпусков Python.

Эти инструкции предназначены для упрощения перехода на будущие версии Python, которые вносят в язык несовместимые изменения. Они позволяют использовать новые возможности на уровне отдельных модулей ещё до того, как они станут стандартными в будущих выпусках Python.

    future_stmt: "from" "__future__" "import" feature ["as" identifier]
                 ("," feature ["as" identifier])*
                 | "from" "__future__" "import" "(" feature ["as" identifier]
                 ("," feature ["as" identifier])* [","] ")"
    feature:     identifier

Инструкции будущих возможностей должны находиться в начале модуля. Перед ними могут встречаться только следующие строки:

- строка документации модуля (если она есть),

- комментарии,

- пустые строки и

- другие инструкции будущих возможностей.

Единственная функциональность, требующая использования инструкции будущих возможностей — это `annotations` (см. PEP 563).

Инструкции будущих возможностей, включающие историческую функциональность, по-прежнему распознаются интерпретатором Python 3. Список таких возможностей включает: `absolute_import`, `division`, `generators`, `generator_stop`, `unicode_literals`, `print_function`, `nested_scopes` и `with_statement`. Все такие инструкции избыточны, поскольку вся эта функциональность уже включена, и сохраняются только для обратной совместимости.

Инструкции будущих возможностей распознаются и обрабатываются особым образом на этапе компиляции: изменения в семантике базовых конструкций часто реализуются за счёт генерации другого кода. В некоторых случаях новая возможность может даже вводить несовместимый синтаксис (например, новое зарезервированное слово), и тогда компилятору требуется по-другому анализировать модуль. Такие решения нельзя откладывать до времени выполнения.

Для каждого конкретного выпуска Python компилятор знает, какие имена возможностей определены, и выдаёт ошибку на этапе компиляции, если инструкция будущих возможностей содержит неизвестное ему имя.

Непосредственная семантика времени выполнения такая же, как у обычной инструкции импорта: существует стандартный модуль `__future__`, описанный далее, и он импортируется обычным образом в момент выполнения инструкции будущих возможностей.

Более существенные аспекты семантики времени выполнения зависят от конкретной функциональности, включаемой инструкцией будущих возможностей.

Обратите внимание, что в этой инструкции нет ничего особенного:

    import __future__ [as name]

Это не инструкция будущих возможностей, а обычная инструкция импорта, не имеющая ни специальной семантики, ни синтаксических ограничений.

Код, который компилируется с помощью встроенных функций `exec()` и `compile()` и при этом находится в модуле `M`, содержащем инструкцию будущих возможностей, по умолчанию будет использовать новый синтаксис или семантику, связанные с этой инструкцией. Это поведение можно изменить с помощью дополнительных аргументов функции `compile()` — подробности см. в её документации.

Инструкция будущих возможностей, введённая в интерактивной командной строке интерпретатора, действует до конца текущего сеанса. Если интерпретатор запущен с опцией `-i`, ему передан скрипт для выполнения, и этот скрипт содержит инструкцию будущих возможностей, то она будет действовать и в интерактивном сеансе, который начинается после выполнения скрипта.

См. также

PEP 236 — Назад в __будущее__

  Первоначальное предложение механизма __future__.

## 7.12. Инструкция `global`

    global_stmt: "global" identifier ("," identifier)*

Инструкция `global` заставляет перечисленные идентификаторы интерпретироваться как глобальные. Без инструкции `global` присвоение глобальной переменной было бы невозможно, хотя свободные переменные могут ссылаться на глобальные без объявления их как глобальных.

Инструкция `global` действует на всю текущую область видимости (модуль, тело функции или определение класса). Если переменная используется или ей присваивается значение до её объявления как глобальной в этой области, выбрасывается исключение `SyntaxError`.

На уровне модуля все переменные являются глобальными, поэтому инструкция `global` не оказывает никакого эффекта. Тем не менее, переменные по-прежнему не должны использоваться или им присваиваться значение до их объявления через `global`. Это ограничение смягчено в интерактивной консоли (REPL).

Примечание для программиста: инструкция `global` является директивой для анализатора. Она применяется только к коду, который анализируется одновременно с инструкцией `global`. В частности, инструкция `global` в строке или объекте кода, переданном встроенной функции `exec()`, не влияет на блок кода, содержащий вызов функции, и код внутри такой строки не подчиняется инструкциям `global` из кода, содержащего вызов функции. То же самое относится к функциям `eval()` и `compile()`.

## 7.13. Инструкция `nonlocal`

    nonlocal_stmt: "nonlocal" identifier ("," identifier)*

Когда определение функции или класса вложено (заключено) в определения других функций, их нелокальные области видимости — это локальные области видимости внешних функций. Инструкция `nonlocal` заставляет перечисленные идентификаторы ссылаться на имена, ранее привязанные в таких нелокальных областях. Она позволяет вложенному коду переназначать эти идентификаторы. Если имя привязано более чем в одной нелокальной области, используется ближайшая привязка. Если имя не привязано ни в одной нелокальной области или таких областей нет, выбрасывается исключение `SyntaxError`.

Инструкция `nonlocal` действует на всю область видимости тела функции или класса. Если переменная используется или ей присваивается значение до её объявления как нелокальной, выбрасывается исключение `SyntaxError`.

См. также

PEP 3104 — Доступ к именам во внешних областях видимости

  Спецификация инструкции `nonlocal`.

Примечание для программиста: инструкция `nonlocal` является директивой для анализатора и применяется только к коду, который анализируется вместе с этой инструкцией. См. примечание к инструкции `global`.

## 7.14. Инструкция `type`

    type_stmt: 'type' identifier [type_params] "=" expression

Инструкция `type` объявляет псевдоним типа, который является экземпляром `typing.TypeAliasType`.

Например, следующая инструкция создаёт псевдоним типа:

    type Point = tuple[float, float]

Этот код примерно эквивалентен следующему:

    annotation-def VALUE_OF_Point():
        return tuple[float, float]
    Point = typing.TypeAliasType("Point", VALUE_OF_Point())

`annotation-def` обозначает область действия аннотации, которая ведёт себя в основном как функция, но имеет несколько небольших отличий.

Значение псевдонима типа вычисляется в области действия аннотации. Оно не вычисляется в момент создания псевдонима типа, а только когда значение запрашивается через атрибут псевдонима `__value__` (см. Lazy evaluation). Это позволяет псевдониму типа ссылаться на имена, которые ещё не определены.

Псевдонимы типов могут быть обобщёнными, если после имени указать список параметров типа. Подробнее см. Generic type aliases.

`type` — это мягкое ключевое слово.

Добавлено в версии 3.12.

См. также

PEP 695 — Синтаксис параметров типа

  Введена инструкция `type` и синтаксис для обобщённых классов и функций.