Простые операторы
Простой оператор состоит из одной логической строки. Несколько простых операторов могут находиться в одной строке, разделенные точкой с запятой. Синтаксис простых операторов:
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-выражения.
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 применяется к всему объёму функции или класса. Если переменная используется или ей присваивается значение до её глобального объявления в области видимости, возникает ошибка SyntaxError.
Примечание для программиста: global является директивой для анализатора. Она применяется только к коду, который анализируется одновременно с оператором global. В частности, оператор global в строке или объекте кода, переданном встроенной функции exec(), не влияет на блок кода, содержащий вызов функции, и код в такой строке не затрагивается операторами global в коде, содержащем вызов функции. То же самое относится к функциям eval() и compile().
7.13. Оператор nonlocal
nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
Когда определение функции или класса вложено (внутри определений других функций), её нелокальные области видимости — это локальные области видимости окружающих функций. Оператор nonlocal указывает интерпретатору, что перечисленные идентификаторы ссылаются на имена, ранее связанные в нелокальных областях видимости. Это позволяет вложенному коду повторно связывать такие нелокальные идентификаторы. Если имя связано более чем в одной нелокальной области видимости, используется ближайшее связывание. Если имя не связано ни в одной нелокальной области видимости или нелокальная область видимости отсутствует, возникает ошибка SyntaxError.
Оператор 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.13/reference/simple_stmts.html