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 ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" | ">>=" | "<<=" | "&=" | "^=" | "|="
(Див. розділ Праймеріз для визначення синтаксису останніх трьох символів.)
Розширене призначення оцінює ціль (яка, на відміну від звичайних операторів призначення, не може бути розпаковуванням) і список виразів, виконує двійкову операцію, специфічну для типу призначення над двома операндами, і призначає результат вихідній цільовій цілі. Ціль оцінюється лише один раз.
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 evaluated and stored in a special class or module
attribute __annotations__
that is a dictionary mapping from variable names (mangled if private) to
evaluated annotations. This attribute is writable and is automatically
created at the start of class or module body execution, if annotations
are found statically.
If the assignment target is not simple (an attribute, subscript node, or parenthesized name), the annotation is evaluated if in class or module scope, but not stored.
Якщо ім’я анотовано в області видимості функції, то це ім’я є локальним для цієї області. Анотації ніколи не оцінюються та зберігаються в областях функцій.
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
) виконується у два кроки:
знайти модуль, завантаживши та ініціалізувавши його, якщо необхідно
визначте ім’я або імена в локальному просторі імен для області, де виникає оператор
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
використовує дещо складніший процес:
знайти модуль, указаний у пункті
from
, завантажуючи та ініціалізуючи його, якщо необхідно;для кожного з ідентифікаторів, указаних у пунктах
import
:перевірте, чи імпортований модуль має атрибут із таким іменем
якщо ні, спробуйте імпортувати підмодуль із такою назвою, а потім знову перевірте імпортований модуль на наявність цього атрибута
якщо атрибут не знайдено, виникає
ImportError
.інакше посилання на це значення зберігається в локальному просторі імен, використовуючи ім’я в реченні
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.
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.