Простые инструкции
Простая инструкция занимает одну логическую строку. Несколько простых инструкций могут находиться в одной строке, если они разделены точками с запятой. Синтаксис простых инструкций:
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 | "*" target
(Синтаксические определения attributeref и subscription см. в разделе Первичные выражения.)
Инструкция присваивания вычисляет список выражений (помните, что это может быть одно выражение или список выражений, разделённых запятыми; последний случай даёт кортеж) и присваивает единственный полученный объект каждому из целевых списков слева направо.
Присваивание определяется рекурсивно в зависимости от формы цели (списка). Если цель является частью изменяемого объекта (ссылкой на атрибут или подпиской), изменяемый объект должен выполнить присваивание и определить его допустимость; если присваивание недопустимо, он может вызвать исключение. Правила, которым следуют различные типы объектов, и вызываемые исключения описаны в определениях типов объектов (см. раздел Стандартная иерархия типов).
Присваивание объекта целевому списку, который может быть заключён в круглые или квадратные скобки, определяется рекурсивно следующим образом.
- Если целевой список состоит из одной цели без завершающей запятой, возможно заключённой в круглые скобки, объект присваивается этой цели.
-
Иначе:
- Если целевой список содержит одну цель со звёздочкой, называемую «целью со звёздочкой»: объект должен быть итерируемым и содержать не меньше элементов, чем число целей в целевом списке минус один. Первые элементы итерируемого объекта присваиваются слева направо целям, расположенным перед целью со звёздочкой. Последние элементы итерируемого объекта присваиваются целям, расположенным после цели со звёздочкой. Список оставшихся элементов итерируемого объекта присваивается цели со звёздочкой (список может быть пустым).
- Иначе: объект должен быть итерируемым и содержать столько же элементов, сколько целей в целевом списке; элементы присваиваются соответствующим целям слева направо.
Присваивание объекта одной цели определяется рекурсивно следующим образом.
-
Если цель — идентификатор (имя):
- Если имя не встречается в инструкции
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. -
Если цель — подписка: вычисляется первичное выражение в ссылке. Затем вычисляется выражение индекса. После этого у первичного объекта вызывается метод
__setitem__()с двумя аргументами: индексом и присваиваемым объектом.Обычно
__setitem__()определён для изменяемых последовательностей (например, списков) и объектов-отображений (например, словарей) и действует следующим образом.Если первичный объект — изменяемая последовательность (например, список), индекс должен быть целым числом. Если он отрицательный, к нему прибавляется длина последовательности. Полученное значение должно быть неотрицательным целым числом, меньшим длины последовательности; после этого последовательности передаётся запрос присвоить присваиваемый объект элементу с этим индексом. Если индекс выходит за допустимые границы, вызывается исключение
IndexError(присваивание элементу последовательности по индексу не может добавлять новые элементы в список).Если первичный объект — объект-отображение (например, словарь), тип индекса должен быть совместим с типом ключей отображения; затем отображению передаётся запрос создать пару ключ/значение, связывающую индекс с присваиваемым объектом. При этом может быть заменена существующая пара ключ/значение с тем же ключом либо добавлена новая пара ключ/значение (если ключа с таким значением ещё не было).
Если цель — срез: первичное выражение должно вычисляться в изменяемый объект-последовательность (например, список). Присваиваемый объект должен быть итерируемым объектом. Нижняя и верхняя границы среза должны быть целыми числами; если они равны
None(или не указаны), по умолчанию используются ноль и длина последовательности. Если какая-либо граница отрицательна, к ней прибавляется длина последовательности. Полученные границы ограничиваются диапазоном от нуля до длины последовательности включительно. Наконец, объекту-последовательности передаётся запрос заменить срез элементами присваиваемой последовательности. Длина среза может отличаться от длины присваиваемой последовательности, изменяя тем самым длину целевой последовательности, если она допускает такие изменения.
Хотя из определения присваивания следует, что пересечения левой и правой частей происходят «одновременно» (например, 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 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__ класса или модуля либо средствами модуля annotationlib.
Если цель присваивания не является простой (это атрибут, узел подписки или имя в круглых скобках), аннотация никогда не вычисляется.
Если имя аннотировано в области видимости функции, это имя является локальным для этой области видимости. В областях видимости функций аннотации никогда не вычисляются и не сохраняются.
Если правая часть присутствует, присваивание с аннотацией выполняет собственно присваивание так, как если бы аннотации не было. Если правая часть отсутствует, а целью является выражение, интерпретатор вычисляет цель, за исключением последнего вызова __setitem__() или __setattr__().
См. также
- PEP 526 — Синтаксис аннотаций переменных
-
Предложение, добавившее синтаксис аннотирования типов переменных (в том числе переменных класса и экземпляра) вместо их описания в комментариях.
- PEP 484 — Подсказки типов
-
Предложение, добавившее модуль
typing, предоставляющий стандартный синтаксис аннотаций типов для средств статического анализа и IDE.
Изменено в версии 3.8: Теперь в правой части присваиваний с аннотациями разрешены те же выражения, что и в обычных присваиваниях. Ранее некоторые выражения (например, выражения-кортежи без круглых скобок) приводили к синтаксической ошибке.
Изменено в версии 3.14: Теперь аннотации лениво вычисляются в отдельной области видимости аннотаций. Если цель присваивания не является простой, аннотации никогда не вычисляются.
7.3. Инструкция 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) выполняется в два этапа:
- поиск модуля, его загрузка и инициализация при необходимости;
- определение имени или имён в текущем пространстве имён для области видимости, в которой встречается инструкция
import, как если бы это была инструкция присваивания (включая семантикуglobalиnonlocal).
Если инструкция содержит несколько предложений (разделённых запятыми), эти два этапа выполняются отдельно для каждого предложения, как если бы предложения были разделены на отдельные инструкции импорта.
Подробное описание первого этапа — поиска и загрузки модулей — приведено в разделе о системе импорта. В нём также описаны различные типы пакетов и модулей, которые можно импортировать, а также все перехватчики, с помощью которых можно настраивать систему импорта. Обратите внимание, что сбой на этом этапе может означать как невозможность найти модуль, так и ошибку при его инициализации, в том числе при выполнении кода модуля.
Если запрошенный модуль успешно получен, он будет доступен в локальном пространстве имён одним из трёх способов:
- Если после имени модуля следует
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__; если она определена, это должна быть последовательность строк — имён, определённых или импортированных этим модулем. Имена, содержащие символы, отличные от ASCII, должны быть в нормализационной форме NFKC; подробности см. в разделе Не-ASCII символы в именах. Все имена, указанные в __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, — 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]
не является инструкцией future; это обычная инструкция импорта без особой семантики или синтаксических ограничений.
Код, скомпилированный вызовами встроенных функций exec() и compile(), выполняемыми в модуле M, содержащем инструкцию future, по умолчанию будет использовать новый синтаксис или семантику, связанную с этой инструкцией. Это поведение можно изменить с помощью необязательных аргументов функции compile() — подробности см. в документации к этой функции.
Инструкция future, введённая в интерактивной подсказке интерпретатора, будет действовать до конца сеанса интерпретатора. Если интерпретатор запущен с параметром -i, ему передано имя скрипта для выполнения, и скрипт содержит инструкцию future, она будет действовать в интерактивном сеансе, запущенном после выполнения скрипта.
См. также
- PEP 236 — Возвращение к __future__
-
Исходное предложение о механизме __future__.
7.12. Инструкция global
global_stmt: "global" identifier ("," identifier)*
Инструкция global предписывает интерпретировать перечисленные идентификаторы как глобальные. Присвоить значение глобальной переменной без global невозможно, хотя свободные переменные могут ссылаться на глобальные без объявления их глобальными.
Инструкция global применяется ко всей текущей области видимости (модулю, телу функции или определению класса). Если переменная используется или ей присваивается значение до её объявления global в этой области видимости, возникает исключение SyntaxError.
На уровне модуля все переменные глобальные, поэтому инструкция global не оказывает влияния. Однако переменные по-прежнему нельзя использовать или изменять до их объявления global. В интерактивной подсказке (REPL) это требование смягчено.
Примечание для программистов: 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 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/reference/simple_stmts.html