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.

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

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

Хоча визначення присвоєння передбачає, що збіги між лівою та правою сторонами є «одночасними» (наприклад, 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                     ::=  "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

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

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

Вираз розширеного присвоєння, як-от 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)]

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

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

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

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

If the right hand side is present, an annotated assignment performs the actual assignment before evaluating annotations (where applicable). 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.

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

Оператор yield семантично еквівалентний виразу yield. Оператор yield можна використовувати, щоб опустити дужки, які в іншому випадку були б потрібні в еквівалентному операторі виразу yield. Наприклад, оператори yield:

yield <expr>
yield from <expr>

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

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

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

Щоб отримати повну інформацію про семантику 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)*

Оператор global — це оголошення, яке зберігається для всього поточного блоку коду. Це означає, що перелічені ідентифікатори слід інтерпретувати як глобальні. Було б неможливо призначити глобальну змінну без global, хоча вільні змінні можуть посилатися на глобальні, не будучи оголошеними глобальними.

Імена, перелічені в операторі global, не можна використовувати в тому самому блоці коду, що текстово передує оператору global.

Імена, перелічені в операторі global, не можна визначати як формальні параметри або як цілі в операторах with або в пунктах except або в списку цілей for , визначення class, визначення функції, оператор import або анотація змінної.

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

Примітка програміста: 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.