# 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
                     | slicing
                     | "*" target

(Див. розділ Праймеріз для визначення синтаксису для attributeref, subscription і slicing.)

Інструкція присвоєння оцінює список виразів (пам’ятайте, що це може бути один вираз або список, розділений комами, останній дає кортеж) і призначає єдиний результуючий об’єкт кожному з цільових списків зліва направо.

Присвоєння визначається рекурсивно залежно від форми цілі (списку). Коли ціль є частиною змінного об’єкта (посилання на атрибут, підписка або зріз), змінний об’єкт повинен остаточно виконати призначення та прийняти рішення про його достовірність і може викликати виняток, якщо призначення є неприйнятним. Правила, яких дотримуються різні типи, і винятки, які виникають, наведені разом із визначенням типів об’єктів (див. розділ Стандартна ієрархія типів).

Призначення об’єкта цільовому списку, необов’язково укладеному в круглі або квадратні дужки, рекурсивно визначається наступним чином.

- Якщо цільовий список є одним цільовим об’єктом без кінцевої коми, необов’язково в дужках, об’єкт призначається цій цільовій цілі.

- ще:

  - Якщо цільовий список містить одну ціль із префіксом зірочки, це називається ціль із зірочкою: об’єкт має бути ітерованим із принаймні такою кількістю елементів, скільки цілей у списку цілей, мінус один. Перші елементи iterable призначаються, зліва направо, цілям перед ціллю, позначеною зірочкою. Останні елементи iterable призначаються цілям після цілі, позначеної зірочкою. Список елементів, що залишилися в iterable, потім призначається позначеній цілі (список може бути порожнім).

  - Інакше: об’єкт має бути ітерованим із такою ж кількістю елементів, як цілей у списку цілей, а елементи призначаються зліва направо відповідним цілям.

Призначення об’єкта одній меті рекурсивно визначається наступним чином.

- Якщо метою є ідентифікатор (ім’я):

  - Якщо ім’я не зустрічається в операторі `global` або `nonlocal` у поточному блоці коду: ім’я прив’язується до об’єкта в поточному локальному просторі імен.

  - Інакше: ім’я прив’язується до об’єкта в глобальному просторі імен або зовнішньому просторі імен, визначеному `nonlocal` відповідно.

  Ім’я повертається, якщо воно вже було зв’язане. Це може призвести до того, що кількість посилань для об’єкта, раніше прив’язаного до імені, досягне нуля, що призведе до звільнення об’єкта та виклику його деструктора (якщо він є).

- Якщо метою є посилання на атрибут: обчислюється основний вираз у посиланні. Він повинен давати об’єкт із присвоюваними атрибутами; якщо це не так, виникає `TypeError`. Тоді цей об’єкт запитується призначити призначений об’єкт даному атрибуту; якщо він не може виконати призначення, він викликає виняток (зазвичай, але не обов’язково `AttributeError`).

  Примітка. Якщо об’єкт є екземпляром класу, а посилання на атрибут міститься з обох сторін оператора присвоєння, вираз у правому боці `a.x` може отримати доступ або до атрибута екземпляра, або (якщо атрибут екземпляра не існує) до класу атрибут. Ліва ціль `a.x` завжди встановлюється як атрибут екземпляра, створюючи його за необхідності. Таким чином, два входження `a.x` не обов’язково посилаються на той самий атрибут: якщо правий вираз посилається на атрибут класу, ліва частина створює новий атрибут екземпляра як ціль призначення: :

      class Cls:
          x = 3             # class variable
      inst = Cls()
      inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3

  Цей опис не обов’язково стосується атрибутів дескрипторів, таких як властивості, створені за допомогою `property()`.

- Якщо метою є підписка: обчислюється основний вираз у посиланні. Він повинен давати або об’єкт змінної послідовності (наприклад, список), або об’єкт відображення (наприклад, словник). Далі обчислюється нижній індекс.

  Якщо основний об’єкт є змінним об’єктом послідовності (наприклад, список), нижній індекс повинен давати ціле число. Якщо він від’ємний, до нього додається довжина послідовності. Отримане значення має бути невід’ємним цілим числом, меншим за довжину послідовності, і послідовності пропонується призначити призначений об’єкт своєму елементу з цим індексом. Якщо індекс виходить за межі діапазону, виникає `IndexError` (присвоєння послідовності з індексом не може додавати нові елементи до списку).

  If the primary is a mapping object (such as a dictionary), the subscript must have a type compatible with the mapping’s key type, and the mapping is then asked to create a key/value pair which maps the subscript to the assigned object. This can either replace an existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed).

  For user-defined objects, the `__setitem__()` method is called with appropriate arguments.

- Якщо метою є нарізка: обчислюється основний вираз у посиланні. Він повинен давати змінний об’єкт послідовності (наприклад, список). Призначений об’єкт має бути об’єктом послідовності того самого типу. Далі обчислюються вирази нижньої та верхньої межі, якщо вони присутні; за замовчуванням нуль і довжина послідовності. Межі повинні обчислюватися як цілі числа. Якщо будь-яка межа негативна, до неї додається довжина послідовності. Отримані межі обрізаються між нулем і довжиною послідовності включно. Нарешті, об’єкту послідовності пропонується замінити зріз елементами призначеної послідовності. Довжина зрізу може відрізнятися від довжини призначеної послідовності, таким чином змінюючи довжину цільової послідовності, якщо це дозволяє цільова послідовність.

У поточній реалізації синтаксис для цілей вважається таким самим, як і для виразів, а недійсний синтаксис відхиляється під час фази генерації коду, викликаючи менш докладні повідомлення про помилки.

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

    x = [0, 1]
    i = 0
    i, x[i] = 1, 2         # i is updated, then x[i] is updated
    print(x)

Дивись також

PEP 3132 - Розширене ітераційне розпакування

  Специфікація функції `*target`.

### 7.2.1. Доповнені заяви про призначення

Розширене присвоєння — це комбінація в одному операторі двійкової операції та оператора присвоєння:

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

(Див. розділ Праймеріз для визначення синтаксису останніх трьох символів.)

Розширене призначення оцінює ціль (яка, на відміну від звичайних операторів призначення, не може бути розпаковуванням) і список виразів, виконує двійкову операцію, специфічну для типу призначення над двома операндами, і призначає результат вихідній цільовій цілі. Ціль оцінюється лише один раз.

An augmented assignment statement like `x += 1` can be rewritten as `x = x + 1` to achieve a similar, but not exactly equal effect. In the augmented version, `x` is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.

На відміну від звичайних завдань, розширені завдання оцінюють ліву сторону перед оцінкою правої сторони. Наприклад, `a[i] += f(x)` спочатку шукає `a[i]`, потім обчислює `f(x)` і виконує додавання, і, нарешті, він записує результат назад до `a[i]`.

За винятком призначення кортежам і декільком цілям в одному операторі, призначення, виконане доповненими операторами призначення, обробляється так само, як і звичайні призначення. Подібним чином, за винятком можливої поведінки на місці, двійкова операція, що виконується розширеним призначенням, є такою самою, як і звичайні двійкові операції.

Для цілей, які є посиланнями на атрибути, застосовується те саме застереження щодо атрибутів класу та екземпляра, що й для звичайних призначень.

### 7.2.2. Анотовані заяви про призначення

Анотація присвоєння — це комбінація в одному операторі анотації змінної або атрибута та необов’язкового оператора призначення:

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

The difference from normal Заяви про призначення is that only a single target is allowed.

The assignment target is considered «simple» if it consists of a single name that is not enclosed in parentheses. For simple assignment targets, if in class or module scope, the annotations are gathered in a lazily evaluated annotation scope. The annotations can be evaluated using the `__annotations__` attribute of a class or module, or using the facilities in the `annotationlib` module.

If the assignment target is not simple (an attribute, subscript node, or parenthesized name), the annotation is never evaluated.

Якщо ім’я анотовано в області видимості функції, то це ім’я є локальним для цієї області. Анотації ніколи не оцінюються та зберігаються в областях функцій.

If the right hand side is present, an annotated assignment performs the actual assignment as if there was no annotation present. If the right hand side is not present for an expression target, then the interpreter evaluates the target except for the last `__setitem__()` or `__setattr__()` call.

Дивись також

PEP 526 - Синтаксис для анотацій змінних

  Пропозиція, яка додала синтаксис для анотування типів змінних (включаючи змінні класу та змінні екземпляра), замість вираження їх через коментарі.

PEP 484 - Тип підказок

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

Змінено в версії 3.8: Now annotated assignments allow the same expressions in the right hand side as regular assignments. Previously, some expressions (like un-parenthesized tuple expressions) caused a syntax error.

Змінено в версії 3.14: Annotations are now lazily evaluated in a separate annotation scope. If the assignment target is not simple, annotations are never evaluated.

## 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)

These equivalences assume that `__debug__` and `AssertionError` refer to the built-in variables with those names. In the current implementation, the built-in variable `__debug__` is `True` under normal circumstances, `False` when optimization is requested (command line option `-O`). The current code generator emits no code for an `assert` statement when optimization is requested at compile time. Note that it is unnecessary to include the source code for the expression that failed in the error message; it will be displayed as part of the stack trace.

Присвоєння `__debug__` є незаконним. Значення для вбудованої змінної визначається під час запуску інтерпретатора.

## 7.4. Оператор `pass`

    pass_stmt: "pass"

`pass` є нульовою операцією — коли вона виконується, нічого не відбувається. Це корисно як заповнювач, коли оператор потрібний синтаксично, але не потрібно виконувати код, наприклад:

    def f(arg): pass    # a function that does nothing (yet)

    class C: pass       # a class with no methods (yet)

## 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

A `yield` statement is semantically equivalent to a yield expression. The `yield` statement can be used to omit the parentheses that would otherwise be required in the equivalent yield expression statement. For example, the yield statements

    yield <expr>
    yield from <expr>

еквівалентні операторам виразу yield

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

Yield expressions and statements are only used when defining a generator function, and are only used in the body of the generator function. Using `yield` in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.

Щоб отримати повну інформацію про семантику `yield`, зверніться до розділу Вирази дохідності.

## 7.8. Оператор `raise`

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

Якщо виразів немає, `raise` повторно викликає виняток, який зараз обробляється, який також відомий як активний виняток. Якщо наразі немає активного винятку, виникає виняток `RuntimeError`, який вказує на те, що це помилка.

В іншому випадку `raise` обчислює перший вираз як об’єкт винятку. Це має бути або підклас, або екземпляр `BaseException`. Якщо це клас, екземпляр винятку буде отримано за потреби шляхом створення екземпляра класу без аргументів.

type винятку — це клас екземпляра винятку, value — це сам екземпляр.

A traceback object is normally created automatically when an exception is raised and attached to it as the `__traceback__` attribute. You can create an exception and set your own traceback in one step using the `with_traceback()` exception method (which returns the same exception instance, with its traceback set to its argument), like so:

    raise Exception("foo occurred").with_traceback(tracebackobj)

The `from` clause is used for exception chaining: if given, the second expression must be another exception class or instance. If the second expression is an exception instance, it will be attached to the raised exception as the `__cause__` attribute (which is writable). If the expression is an exception class, the class will be instantiated and the resulting exception instance will be attached to the raised exception as the `__cause__` attribute. If the raised exception is not handled, both exceptions will be printed:

    >>> try:
    ...     print(1 / 0)
    ... except Exception as exc:
    ...     raise RuntimeError("Something bad happened") 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("Something bad happened") from exc
    RuntimeError: Something bad happened

A similar mechanism works implicitly if a new exception is raised when an exception is already being handled. An exception may be handled when an `except` or `finally` clause, or a `with` statement, is used. The previous exception is then attached as the new exception’s `__context__` attribute:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Something bad happened")
    ...
    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("Something bad happened")
    RuntimeError: Something bad happened

Exception chaining can be explicitly suppressed by specifying `None` in the `from` clause:

    >>> try:
    ...     print(1 / 0)
    ... except:
    ...     raise RuntimeError("Something bad happened") from None
    ...
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    RuntimeError: Something bad happened

Додаткову інформацію про винятки можна знайти в розділі Винятки, а інформацію про обробку винятків — у розділі Оператор try.

Змінено в версії 3.3: `None` тепер дозволено як `Y` у `raise X from Y`.

Added the `__suppress_context__` attribute to suppress automatic display of the exception context.

Змінено в версії 3.11: If the traceback of the active exception is modified in an `except` clause, a subsequent `raise` statement re-raises the exception with the modified traceback. Previously, the exception was re-raised with the traceback it had when it was caught.

## 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:     "import" module ["as" identifier] ("," module ["as" identifier])*
                     | "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" relative_module "import" "*"
    module:          (identifier ".")* identifier
    relative_module: "."* module | "."+

Базовий оператор імпорту (без пропозиції `from`) виконується у два кроки:

1. знайти модуль, завантаживши та ініціалізувавши його, якщо необхідно

2. визначте ім’я або імена в локальному просторі імен для області, де виникає оператор `import`.

Якщо оператор містить кілька пунктів (розділених комами), два кроки виконуються окремо для кожного пункту, так само, як якщо б пункти були розділені на окремі оператори імпорту.

The details of the first step, finding and loading modules, are described in greater detail in the section on the import system, which also describes the various types of packages and modules that can be imported, as well as all the hooks that can be used to customize the import system. Note that failures in this step may indicate either that the module could not be located, or that an error occurred while initializing the module, which includes execution of the module’s code.

Якщо запитуваний модуль успішно отримано, він стане доступним у локальному просторі імен одним із трьох способів:

- Якщо ім’я модуля супроводжується `as`, тоді ім’я після `as` прив’язується безпосередньо до імпортованого модуля.

- Якщо інше ім’я не вказано, а імпортований модуль є модулем верхнього рівня, ім’я модуля зв’язується в локальному просторі імен як посилання на імпортований модуль

- Якщо імпортований модуль не є модулем верхнього рівня, тоді ім’я пакета верхнього рівня, який містить модуль, прив’язується до локального простору імен як посилання на пакет верхнього рівня. Доступ до імпортованого модуля потрібно отримати, використовуючи його повне кваліфіковане ім’я, а не безпосередньо

Форма `from` використовує дещо складніший процес:

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

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

   1. перевірте, чи імпортований модуль має атрибут із таким іменем

   2. якщо ні, спробуйте імпортувати підмодуль із такою назвою, а потім знову перевірте імпортований модуль на наявність цього атрибута

   3. якщо атрибут не знайдено, виникає `ImportError`.

   4. інакше посилання на це значення зберігається в локальному просторі імен, використовуючи ім’я в реченні `as`, якщо воно присутнє, інакше використовується ім’я атрибута

Приклади:

    import foo                 # foo imported and bound locally
    import foo.bar.baz         # foo, foo.bar, and foo.bar.baz imported, foo bound locally
    import foo.bar.baz as fbb  # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb
    from foo.bar import baz    # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz
    from foo import attr       # foo imported and foo.attr bound as attr

Якщо список ідентифікаторів замінено зірочкою (`'*'`), усі загальнодоступні імена, визначені в модулі, прив’язуються до локального простору імен для області, де виникає оператор `import`.

Відкриті імена, визначені модулем, визначаються шляхом перевірки простору імен модуля для змінної з назвою `__all__`; якщо визначено, це має бути послідовність рядків, які є іменами, визначеними або імпортованими цим модулем. Усі назви, наведені в `__all__`, вважаються загальнодоступними та мають існувати. Якщо `__all__` не визначено, набір загальнодоступних імен включає всі імена, знайдені в просторі імен модуля, які не починаються зі символу підкреслення (`'_'`). `__all__` має містити весь публічний API. Це призначено для уникнення випадкового експорту елементів, які не є частиною API (наприклад, бібліотечних модулів, які були імпортовані та використані в модулі).

Форма імпорту із символом підстановки — `з імпорту модуля *` — дозволена лише на рівні модуля. Спроба використати його у визначеннях класу чи функції викличе `SyntaxError`.

Визначаючи, який модуль імпортувати, не потрібно вказувати абсолютну назву модуля. Коли модуль або пакунок міститься в іншому пакунку, можна виконати відносний імпорт у той самий верхній пакунок, не вказуючи назву пакунка. Використовуючи крапки на початку у вказаному модулі чи пакеті після `from`, ви можете вказати, наскільки високо потрібно перейти вгору по поточній ієрархії пакету, не вказуючи точні назви. Одна крапка на початку означає поточний пакет, у якому існує модуль, що виконує імпорт. Дві крапки означають підвищення на один рівень пакета. Три крапки — це два рівні вище тощо. Отже, якщо ви виконаєте `з . імпортуйте mod` з модуля в пакеті `pkg`, тоді ви імпортуєте `pkg.mod`. Якщо ви виконаєте `from ..subpkg2 import mod` з `pkg.subpkg1`, ви імпортуєте `pkg.subpkg2.mod`. Специфікація відносного імпорту міститься в розділі Відносний імпорт пакетів.

`importlib.import_module()` надається для підтримки програм, які динамічно визначають модулі для завантаження.

Викликає подію аудиту `import` з аргументами `module`, `filename`, `sys.path`, `sys.meta_path`, `sys.path_hooks`.

### 7.11.1. Майбутні заяви

future statement — це вказівка компілятору про те, що певний модуль має бути скомпільовано з використанням синтаксису чи семантики, які будуть доступні у визначеному майбутньому випуску Python, де ця функція стане стандартною.

Заява майбутнього призначена для полегшення переходу на майбутні версії Python, які вносять несумісні зміни в мову. Це дозволяє використовувати нові функції окремо для кожного модуля до випуску, у якому ця функція стане стандартною.

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

У верхній частині модуля має бути майбутня заява. Єдині рядки, які можуть відображатися перед майбутнім оператором:

- рядок документації модуля (якщо є),

- коментарі,

- порожні рядки та

- інші майбутні заяви.

Єдина функція, яка вимагає використання оператора future, це `анотації` (див. PEP 563).

Python 3 усе ще розпізнає всі історичні функції, увімкнені оператором future. Список включає `absolute_import`, `division`, `generators`, `generator_stop`, `unicode_literals`, `print_function`, `nested_scopes` і `with_statement`. Усі вони зайві, оскільки завжди ввімкнені та зберігаються лише для зворотної сумісності.

Майбутній оператор розпізнається та обробляється спеціально під час компіляції: зміни в семантиці основних конструкцій часто впроваджуються шляхом генерації іншого коду. Може навіть статися так, що нова функція вводить новий несумісний синтаксис (наприклад, нове зарезервоване слово), і в цьому випадку компілятору може знадобитися розібрати модуль по-іншому. Такі рішення не можуть бути відкладені до часу виконання.

Для будь-якого конкретного випуску компілятор знає, які назви функцій були визначені, і викликає помилку під час компіляції, якщо майбутній оператор містить функцію, яка йому невідома.

Пряма семантика часу виконання така ж, як і для будь-якого оператора імпорту: є стандартний модуль `__future__`, описаний пізніше, і його буде імпортовано звичайним способом під час виконання оператора майбутнього.

Цікава семантика часу виконання залежить від конкретної функції, увімкненої майбутнім оператором.

Зауважте, що в заяві немає нічого особливого:

    import __future__ [as name]

Це не заява про майбутнє; це звичайний оператор імпорту без спеціальних семантичних або синтаксичних обмежень.

Code compiled by calls to the built-in functions `exec()` and `compile()` that occur in a module `M` containing a future statement will, by default, use the new syntax or semantics associated with the future statement. This can be controlled by optional arguments to `compile()` — see the documentation of that function for details.

Майбутній оператор, набраний у підказці інтерактивного перекладача, матиме чинність до кінця сеансу перекладача. Якщо інтерпретатор запускається з параметром `-i`, йому передається ім’я сценарію для виконання, і сценарій містить майбутній оператор, він діятиме в інтерактивному сеансі, розпочатому після виконання сценарію.

Дивись також

PEP 236 - Назад у __future__

  Оригінальна пропозиція щодо механізму __future__.

## 7.12. Оператор `global`

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

The `global` statement causes the listed identifiers to be interpreted as globals. It would be impossible to assign to a global variable without `global`, although free variables may refer to globals without being declared global.

The `global` statement applies to the entire current scope (module, function body or class definition). A `SyntaxError` is raised if a variable is used or assigned to prior to its global declaration in the scope.

At the module level, all variables are global, so a `global` statement has no effect. However, variables must still not be used or assigned to prior to their `global` declaration. This requirement is relaxed in the interactive prompt (REPL).

Примітка програміста: `global` — це директива для аналізатора. Це стосується лише коду, аналізованого одночасно з оператором `global`. Зокрема, оператор `global`, що міститься в рядку або об’єкті коду, що надається вбудованій функції `exec()`, не впливає на блок коду, що містить виклик функції, і код, що міститься в таких на рядок не впливають оператори `global` у коді, що містить виклик функції. Те саме стосується функцій `eval()` і `compile()`.

## 7.13. Оператор `nonlocal`

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

When the definition of a function or class is nested (enclosed) within the definitions of other functions, its nonlocal scopes are the local scopes of the enclosing functions. The `nonlocal` statement causes the listed identifiers to refer to names previously bound in nonlocal scopes. It allows encapsulated code to rebind such nonlocal identifiers. If a name is bound in more than one nonlocal scope, the nearest binding is used. If a name is not bound in any nonlocal scope, or if there is no nonlocal scope, a `SyntaxError` is raised.

The `nonlocal` statement applies to the entire scope of a function or class body. A `SyntaxError` is raised if a variable is used or assigned to prior to its nonlocal declaration in the scope.

Дивись також

PEP 3104 - Доступ до імен у зовнішніх областях

  Специфікація оператора `nonlocal`.

Programmer’s note: `nonlocal` is a directive to the parser and applies only to code parsed along with it. See the note for the `global` statement.

## 7.14. The `type` statement

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

The `type` statement declares a type alias, which is an instance of `typing.TypeAliasType`.

For example, the following statement creates a type alias:

    type Point = tuple[float, float]

This code is roughly equivalent to:

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

`annotation-def` indicates an annotation scope, which behaves mostly like a function, but with several small differences.

The value of the type alias is evaluated in the annotation scope. It is not evaluated when the type alias is created, but only when the value is accessed through the type alias’s `__value__` attribute (see Lazy evaluation). This allows the type alias to refer to names that are not yet defined.

Type aliases may be made generic by adding a type parameter list after the name. See Generic type aliases for more.

`type` is a soft keyword.

Added in version 3.12.

Дивись також

PEP 695 - Type Parameter Syntax

  Introduced the `type` statement and syntax for generic classes and functions.