Простые операторы
Простой оператор состоит из одной логической строки. Несколько простых операторов могут располагаться в одной строке, разделенные точкой с запятой. Синтаксис простых операторов:
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.)
Оператор присваивания вычисляет список выражений (помните, что это может быть одно выражение или список выражений, разделённых запятыми, последний из которых даёт кортеж) и присваивает единственный полученный объект каждому списку целей слева направо.
Присваивание определяется рекурсивно в зависимости от формы списка целей. Когда цель является частью изменяемого объекта (ссылка на атрибут, подстановка или среза), изменяемый объект должен в конечном итоге выполнить присваивание и решить о его корректности, и может выбросить исключение, если присваивание неприемлемо. Правила, используемые различными типами, и вызываемые исключения, даны с определением типов объектов (см. раздел Стандартная иерархия типов).
Присваивание объекта списку целей, необязательно заключённому в скобки или квадратные скобки, рекурсивно определяется следующим образом.
- Если список целей — это единственная цель без запятой, необязательно в скобках, объект присваивается этой цели.
-
В противном случае:
- Если список целей содержит одну цель с префиксом звёздочкой, так называемую «звёздную» цель: объект должен быть итерируемым с по крайней мере таким же количеством элементов, как и целей в списке целей, минус один. Первые элементы итерируемого объекта присваиваются целям перед звёздной целью слева направо. Последние элементы итерируемого объекта присваиваются целям после звёздной цели. Список оставшихся элементов в итерируемом объекте затем присваивается звёздной цели (список может быть пустым).
- В противном случае: объект должен быть итерируемым с таким же количеством элементов, что и целей в списке целей, и элементы присваиваются соответствующим целям слева направо.
Присваивание объекта одной цели рекурсивно определяется следующим образом.
-
Если цель — это идентификатор (имя):
- Если имя не встречается в операторе
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 в обычных условиях, 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 и операторы 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) выполняется в два этапа:
- поиск модуля, его загрузка и инициализация при необходимости
- определение имени или имён в локальном пространстве имён для области видимости, где находится оператор
import.
Когда оператор содержит несколько фрагментов (разделенных запятыми), эти два этапа выполняются отдельно для каждого фрагмента, как если бы фрагменты были разделены в отдельные операторы импорта.
Подробности первого этапа, поиска и загрузки модулей, описаны более подробно в разделе по системе импорта, который также описывает различные типы пакетов и модулей, которые могут быть импортированы, а также все доступные инструменты для настройки системы импорта. Обратите внимание, что ошибки на этом этапе могут указывать на то, что модуль не был найден или произошла ошибка при его инициализации, включая выполнение кода модуля.
Если запрашиваемый модуль получен успешно, он будет доступен в локальном пространстве имён одним из трёх способов:
- Если имя модуля следует за
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 (например, модулей библиотек, которые были импортированы и использованы в модуле).
Форма импорта с подстановкой звёздочки — 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. Операторы будущего
Оператор будущего — это директива компилятору о том, что данный модуль должен быть скомпилирован с использованием синтаксиса или семантики, которые будут доступны в указанной будущей версии Python, где функция станет стандартной.
Оператор будущего предназначен для облегчения миграции на будущие версии Python, которые вносят несовместимые изменения в язык. Он позволяет использовать новые возможности на модульном уровне до выпуска, в котором функция становится стандартной.
future_stmt ::= "from" "__future__" "import" feature ["as" identifier]
("," feature ["as" identifier])*
| "from" "__future__" "import" "(" feature ["as" identifier]
("," feature ["as" identifier])* [","] ")"
feature ::= identifier
Оператор будущего должен располагаться в начале модуля. Перед оператором будущего могут располагаться только:
- документация модуля (если есть),
- комментарии,
- пустые строки и
- другие операторы будущего.
Единственная функция, требующая использования оператора будущего, это annotations (см. PEP 563).
Все исторические функции, активированные оператором будущего, по-прежнему распознаются Python 3. Список включает absolute_import, division, generators, generator_stop, unicode_literals, print_function, nested_scopes и with_statement. Они все избыточны, так как всегда включены, и сохранены только для обратной совместимости.
Оператор будущего распознаётся и обрабатывается особым образом на этапе компиляции: Изменения в семантике основных конструкций часто реализуются путём генерации разного кода. Может даже случиться, что новая функция вводит новый несовместимый синтаксис (например, новое ключевое слово), в этом случае компилятор может потребовать другого разбора модуля. Такие решения не могут быть отложены до времени выполнения.
Для каждой версии компилятор знает, какие имена функций были определены, и генерирует ошибку компиляции, если оператор будущего содержит функцию, не известную ему.
Прямая семантика времени выполнения такая же, как и для любого оператора импорта: существует стандартный модуль __future__, описанный позже, и он импортируется обычным способом в момент выполнения оператора будущего.
Интересная семантика времени выполнения зависит от конкретной функции, активированной оператором будущего.
Обратите внимание, что оператор:
import __future__ [as name]
Это не оператор будущего; это обычный оператор импорта без специальной семантики или синтаксических ограничений.
Код, скомпилированный при вызовах встроенных функций exec() и compile(), которые встречаются в модуле M с оператором будущего, по умолчанию будут использовать новый синтаксис или семантику, связанные с оператором будущего. Это можно контролировать с помощью необязательных аргументов для compile() — см. документацию этой функции для получения подробной информации.
Оператор будущего, набранный в интерактивном интерпретаторе, вступит в силу для остальной сессии интерпретатора. Если интерпретатор запущен с опцией -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)*
Когда определение функции или класса вложено (окружено) внутри определений других функций, его нелокальные области — это локальные области окружающих функций. Оператор nonlocal заставляет перечисленные идентификаторы ссылаться на имена, ранее связанные в нелокальных областях. Он позволяет вложенному коду повторно связывать такие нелокальные идентификаторы. Если имя связано более чем в одной нелокальной области, используется ближайшая связь. Если имя не связано ни в одной нелокальной области или если нелокальной области нет, возникает SyntaxError.
Оператор nonlocal применим ко всей области тела функции или класса. Если переменная используется или присваивается до её объявления nonlocal в области, возникает SyntaxError.
Примечание программиста: 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