Spec-Zone.ru › Python 3.12

Простые операторы

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

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

(Синтаксические определения ссылки на атрибут, индексации и среза см. в разделе Первичные выражения.)

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

Присваивание определяется рекурсивно в зависимости от формы цели (списка). Если цель является частью изменяемого объекта (ссылкой на атрибут, индексацией или срезом), изменяемый объект должен в конечном счёте выполнить присваивание и определить, допустимо ли оно; если присваивание недопустимо, может быть возбуждено исключение. Правила, которым следуют различные типы, и возбуждаемые исключения приводятся в определениях типов объектов (см. раздел Стандартная иерархия типов).

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

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

    • Если список целей содержит одну цель со звёздочкой перед ней, называемую «целью со звёздочкой»: объект должен быть итерируемым и содержать не менее чем на один элемент меньше, чем целей в списке. Первые элементы итерируемого объекта присваиваются слева направо целям перед целью со звёздочкой. Последние элементы итерируемого объекта присваиваются целям после цели со звёздочкой. Список оставшихся элементов итерируемого объекта затем присваивается цели со звёздочкой (список может быть пустым).
    • Иначе: объект должен быть итерируемым и содержать столько же элементов, сколько целей в списке; элементы присваиваются соответствующим целям слева направо.

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

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

    • Если имя не встречается в операторе 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 (присваивание элементу последовательности по индексу не может добавлять новые элементы в список).

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

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

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

Особенность реализации 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)]

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

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

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

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

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

См. также

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

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

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

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

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

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, а при запросе оптимизации (параметр командной строки -O) — False. При запросе оптимизации на этапе компиляции текущий генератор кода не создаёт код для оператора 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 используются только при определении функции генератора и только в её теле. Использования yield в определении функции достаточно, чтобы это определение создало функцию-генератор, а не обычную функцию.

Полное описание семантики yield см. в разделе Выражения yield.

7.8. Оператор raise

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

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

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

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

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

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

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

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

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

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

Связывание исключений можно явно отключить, указав None в блоке from:

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

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

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

7.9. Оператор break

break_stmt ::= "break"

break может синтаксически находиться только внутри цикла for или while, но не внутри определения функции или класса, вложенного в этот цикл.

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

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

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

7.10. Оператор continue

continue_stmt ::= "continue"

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

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

7.11. Оператор import

import_stmt     ::= "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.

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

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

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

  • Если после имени модуля следует 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 (например, библиотечных модулей, импортированных и используемых внутри модуля).

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

При указании импортируемого модуля не обязательно указывать его абсолютное имя. Если модуль или пакет находится внутри другого пакета, можно выполнить относительный импорт в пределах того же пакета верхнего уровня, не указывая имя пакета. С помощью начальных точек в указанном после from имени модуля или пакета можно задать, насколько высоко нужно подняться по иерархии текущего пакета, не указывая точные имена. Одна начальная точка означает текущий пакет, в котором находится модуль, выполняющий импорт. Две точки означают подъём на один уровень пакета. Три точки — на два уровня и так далее. Поэтому при выполнении from . import 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

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

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

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

Оператор future должен находиться в начале модуля. Перед оператором future могут располагаться только следующие строки:

  • строка документации модуля (если она есть),
  • комментарии,
  • пустые строки и
  • другие операторы future.

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

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

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

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

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

Интересные особенности семантики во время выполнения зависят от конкретной возможности, включённой оператором future.

Обратите внимание, что в операторе

import __future__ [as name]

нет ничего особенного: это обычный оператор импорта без особой семантики или ограничений синтаксиса.

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

Оператор future, введённый в интерактивной командной строке интерпретатора, действует до конца сеанса. Если интерпретатор запущен с параметром -i, ему передано имя скрипта для выполнения, а скрипт содержит оператор future, этот оператор будет действовать и в интерактивном сеансе, запущенном после выполнения скрипта.

См. также

PEP 236 — Возвращение к __future__

Исходное предложение о механизме __future__.

7.12. Оператор global

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

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

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

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

7.13. Оператор nonlocal

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

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

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

См. также

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

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

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

7.14. Оператор type

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

Оператор type объявляет псевдоним типа, являющийся экземпляром typing.TypeAliasType.

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

type Point = tuple[float, float]

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

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

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

Значение псевдонима типа вычисляется в области видимости аннотаций. Оно вычисляется не при создании псевдонима, а только при обращении к нему через атрибут __value__ псевдонима типа (см. Ленивое вычисление). Благодаря этому псевдоним типа может ссылаться на имена, которые ещё не определены.

Псевдонимы типов можно сделать обобщёнными, добавив список параметров типа после имени. Подробнее см. в разделе Обобщённые псевдонимы типов.

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

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

См. также

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

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

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/reference/simple_stmts.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API