7. Простые заявления¶
Простое утверждение состоит из одной логической строки. Несколько простых утверждений могут находиться на одной строке, разделенные точкой с запятой. Синтаксис простых утверждений следующий:
simple_stmt ::=expression_stmt
|assert_stmt
|assignment_stmt
|augmented_assignment_stmt
|annotated_assignment_stmt
|pass_stmt
|del_stmt
|return_stmt
|yield_stmt
|raise_stmt
|break_stmt
|continue_stmt
|import_stmt
|future_stmt
|global_stmt
|nonlocal_stmt
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 implementation detail: В текущей реализации синтаксис для целей принимается таким же, как и для выражений, а неправильный синтаксис отклоняется на этапе генерации кода, что приводит к менее подробным сообщениям об ошибках.
Хотя определение присваивания подразумевает, что пересечения между левой и правой сторонами являются «одновременными» (например, 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]
.
За исключением присваивания кортежам и нескольким целям в одном операторе, присваивание, выполняемое дополненными операторами присваивания, обрабатывается так же, как и обычные присваивания. Аналогично, за исключением возможного поведения вместо, бинарные операции, выполняемые дополненным присваиванием, не отличаются от обычных бинарных операций.
Для целей, которые являются ссылками на атрибуты, применяются те же caveat about class and instance attributes, что и для обычных присвоений.
7.2.2. Аннотированные заявления о назначении¶
Присвоение Annotation - это сочетание в одном операторе аннотации переменной или атрибута и необязательного оператора присваивания:
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 expression. Оператор yield можно использовать для того, чтобы опустить круглые скобки, которые в противном случае потребовались бы в эквивалентном операторе выражения yield. Например, оператор yield
yield <expr>
yield from <expr>
эквивалентны операторам выражения yield
(yield <expr>)
(yield from <expr>)
Выражения и утверждения yield используются только при определении функции generator и только в теле функции-генератора. Использование yield в определении функции достаточно для того, чтобы это определение создало генераторную функцию вместо обычной функции.
Для получения подробной информации о семантике yield
обратитесь к разделу Выражения доходности.
7.8. Оператор raise
¶
raise_stmt ::= "raise" [expression
["from"expression
]]
Если выражений нет, raise
повторно вызывает исключение, которое обрабатывается в данный момент, которое также известно как активное исключение. Если в данный момент активного исключения нет, то поднимается исключение RuntimeError
, указывающее, что это ошибка.
В противном случае raise
оценивает первое выражение как объект исключения. Он должен быть либо подклассом, либо экземпляром BaseException
. Если это класс, экземпляр исключения будет получен при необходимости путем инстанцирования класса без аргументов.
type исключения - это класс экземпляра исключения, value - сам экземпляр.
Объект traceback обычно создается автоматически при возникновении исключения и присоединяется к нему в качестве атрибута __traceback__
, который доступен для записи. Вы можете создать исключение и установить свой собственный traceback за один шаг, используя метод with_traceback()
exception (который возвращает один и тот же экземпляр исключения, а его 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>
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>
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>
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
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
.
Добавлено в версии 3.3: Атрибут __suppress_context__
для подавления автоматического отображения контекста исключения.
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
.
Если утверждение содержит несколько пунктов (разделенных запятыми), эти два шага выполняются отдельно для каждого пункта, как если бы пункты были разделены на отдельные утверждения импорта.
Детали первого шага, поиска и загрузки модулей, более подробно описаны в разделе import system, где также описаны различные типы пакетов и модулей, которые могут быть импортированы, а также все крючки, которые могут быть использованы для настройки системы импорта. Обратите внимание, что неудачи на этом шаге могут указывать либо на то, что модуль не может быть найден, или на то, что произошла ошибка при инициализации модуля, которая включает выполнение кода модуля.
Если запрашиваемый модуль успешно найден, он будет доступен в локальном пространстве имен одним из трех способов:
Если за именем модуля следует
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()
предоставляется для поддержки приложений, которые динамически определяют загружаемые модули.
Поднимает auditing event import
с аргументами module
, filename
, sys.path
, sys.meta_path
, sys.path_hooks
.
7.11.1. Заявления о будущем¶
future statement - это указание компилятору, что конкретный модуль должен быть скомпилирован с использованием синтаксиса или семантики, которые будут доступны в указанном будущем выпуске 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
Заявление о будущем должно находиться в верхней части модуля. Единственными строками, которые могут появиться перед будущим утверждением, являются:
docstring модуля (если есть),
комментарии,
пустые строки, и
другие будущие заявления.
Единственная функция, которая требует использования оператора future, это annotations
(см. PEP 563).
Все исторические функции, включенные с помощью оператора future, по-прежнему распознаются Python 3. Список включает absolute_import
, division
, generators
, generator_stop
, unicode_literals
, print_function
, nested_scopes
и with_statement
. Все они избыточны, поскольку всегда включены, и сохраняются только для обратной совместимости.
Будущее утверждение распознается и обрабатывается особым образом во время компиляции: Изменения в семантике основных конструкций часто реализуются путем генерации другого кода. Может даже случиться так, что новая функция вводит новый несовместимый синтаксис (например, новое зарезервированное слово), и в этом случае компилятору может понадобиться по-другому разобрать модуль. Такие решения не могут быть отложены до времени выполнения.
Для любого данного выпуска компилятор знает, какие имена функций были определены, и выдает ошибку времени компиляции, если оператор future содержит неизвестную ему функцию.
Семантика прямого выполнения такая же, как и для любого оператора import: существует стандартный модуль __future__
, описанный позже, и он будет импортирован обычным образом в момент выполнения оператора future.
Интересная семантика во время выполнения зависит от конкретной функции, включенной в утверждение future.
Обратите внимание, что в утверждении: нет ничего особенного:
import __future__ [as name]
Это не оператор будущего; это обычный оператор импорта, не имеющий специальной семантики или синтаксических ограничений.
Код, скомпилированный вызовами встроенных функций exec()
и compile()
, которые происходят в модуле M
, содержащем будущее утверждение, по умолчанию будет использовать новый синтаксис или семантику, связанную с будущим утверждением. Это можно контролировать с помощью необязательных аргументов к compile()
— подробнее см. документацию к этой функции.
Утверждение будущего, набранное в подсказке интерактивного интерпретатора, будет действовать до конца сеанса интерпретатора. Если интерпретатор запущен с опцией -i
, ему передано имя сценария для выполнения, и сценарий включает оператор future, он будет действовать в интерактивной сессии, запущенной после выполнения сценария.
См.также
- PEP 236 - Назад в __будущее_
Первоначальное предложение для механизма __future__.
7.12. Оператор global
¶
global_stmt ::= "global"identifier
(","identifier
)*
Утверждение global
является объявлением, которое сохраняется для всего текущего блока кода. Это означает, что перечисленные идентификаторы должны интерпретироваться как глобальные. Без global
присвоение глобальной переменной невозможно, хотя свободные переменные могут ссылаться на глобальные переменные, не будучи объявленными глобальными.
Имена, перечисленные в операторе global
, не должны использоваться в том же блоке кода, текстуально предшествующем этому оператору global
.
Имена, перечисленные в операторе global
, не должны быть определены как формальные параметры, или как цели в операторах with
или в предложениях except
, или в списке целей for
, определении class
, определении функции, операторе import
или аннотации переменной.
CPython implementation detail: Текущая реализация не обеспечивает соблюдение некоторых из этих ограничений, но программы не должны злоупотреблять этой свободой, так как будущие реализации могут обеспечить их соблюдение или молчаливое изменение смысла программы.
Примечание программиста: global
- это директива синтаксическому анализатору. Она применяется только к коду, разбираемому одновременно с оператором global
. В частности, оператор global
, содержащийся в строке или объекте кода, передаваемом встроенной функции exec()
, не влияет на блок кода, содержащий вызов функции, и код, содержащийся в такой строке, не затрагивается операторами global
в коде, содержащем вызов функции. То же самое относится к функциям eval()
и compile()
.
7.13. Оператор nonlocal
¶
nonlocal_stmt ::= "nonlocal"identifier
(","identifier
)*
Оператор nonlocal
заставляет перечисленные идентификаторы ссылаться на ранее связанные переменные в ближайшей охватывающей области видимости, исключая глобальные. Это важно, поскольку по умолчанию при связывании сначала выполняется поиск в локальном пространстве имен. Это утверждение позволяет инкапсулированному коду перепривязывать переменные за пределами локальной области видимости, кроме глобальной (модульной) области видимости.
Имена, перечисленные в операторе nonlocal
, в отличие от имен, перечисленных в операторе global
, должны ссылаться на уже существующие привязки в объемлющей области (область, в которой должна быть создана новая привязка, не может быть определена однозначно).
Имена, перечисленные в операторе nonlocal
, не должны сталкиваться с уже существующими привязками в локальной области видимости.