Составные операторы
Составные операторы содержат (группы) других операторов; они каким-либо образом влияют на или управляют выполнением этих других операторов. В общем случае составные операторы занимают несколько строк, хотя в простых вариантах весь составной оператор может быть помещен в одну строку.
Операторы if, while и for реализуют традиционные конструкции управления потоком. Оператор try определяет обработчики исключений и/или код очистки для группы операторов, а оператор with позволяет выполнять код инициализации и завершения вокруг блока кода. Определения функций и классов также являются синтаксически составными операторами.
Составной оператор состоит из одного или нескольких «определений». Определение состоит из заголовка и «блока». Заголовки определений конкретного составного оператора находятся на одном уровне отступа. Каждый заголовок определения начинается с уникального ключевого слова и заканчивается двоеточием. Блок — это группа операторов, управляемая определением. Блок может содержать один или несколько операторов, разделенных точкой с запятой, в одной строке с заголовком, после двоеточия, или он может содержать один или несколько операторов с отступами в последующих строках. Только последний вид блока может содержать вложенные составные операторы; следующее некорректно, в основном потому, что не было бы понятно, к какому определению if относится последующее определение else:
if test1: if test2: print(x)
Также обратите внимание, что в этом контексте точка с запятой имеет более высокий приоритет, чем двоеточие, поэтому в следующем примере будут выполнены либо все, либо ни один из вызовов print():
if x < y < z: print(x); print(y); print(z)
Подводя итог:
compound_stmt ::= if_stmt
| while_stmt
| for_stmt
| try_stmt
| with_stmt
| match_stmt
| funcdef
| classdef
| async_with_stmt
| async_for_stmt
| async_funcdef
suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement ::= stmt_list NEWLINE | compound_stmt
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Обратите внимание, что операторы всегда заканчиваются NEWLINE и, возможно, за ним следует DEDENT. Также обратите внимание, что необязательные дополнительные определения всегда начинаются с ключевого слова, которое не может начинать оператор, таким образом, нет неоднозначностей (проблема «висящего else» в Python решена требованием отступов вложенных операторов if).
Форматирование правил грамматики в следующих разделах размещает каждое определение на отдельной строке для большей ясности.
8.1. Оператор if
Оператор if используется для условного выполнения:
if_stmt ::= "if" assignment_expression ":" suite
("elif" assignment_expression ":" suite)*
["else" ":" suite]
Он выбирает ровно один из блоков, оценивая выражения по одному до тех пор, пока не будет найдено истинное (см. раздел Булевы операции для определения истинного и ложного значения); затем выполняется этот блок (и никакая другая часть оператора if не выполняется или оценивается). Если все выражения ложны, выполняется блок определения else, если он присутствует.
8.2. Оператор while
Оператор while используется для многократного выполнения, пока выражение истинно:
while_stmt ::= "while" assignment_expression ":" suite
["else" ":" suite]
Это многократно проверяет выражение и, если оно истинно, выполняет первый блок; если выражение ложно (что может быть впервые при проверке), выполняется блок определения else, если он присутствует, и цикл завершается.
Оператор break, выполненный в первом блоке, завершает цикл, не выполняя блок определения else. Оператор continue, выполненный в первом блоке, пропускает остальную часть блока и возвращается к проверке выражения.
8.3. Оператор for
Оператор for используется для итерирования по элементам последовательности (например, строки, кортежа или списка) или другого итерируемого объекта:
for_stmt ::= "for" target_list "in" starred_list ":" suite
["else" ":" suite]
Выражение starred_list вычисляется один раз; оно должно возвращать итерируемый объект. Для этого итерируемого объекта создается итератор. Первый элемент, предоставляемый итератором, присваивается списку целей по стандартным правилам присваивания (см. Операторы присваивания), и выполняется блок. Это повторяется для каждого элемента, предоставляемого итератором. Когда итератор исчерпан, выполняется блок в определении else, если он присутствует, и цикл завершается.
Оператор break, выполненный в первом блоке, завершает цикл, не выполняя блок определения else. Оператор continue, выполненный в первом блоке, пропускает остальную часть блока и переходит к следующему элементу или к определению else, если следующего элемента нет.
Цикл for выполняет присваивание переменным в списке целей. Это перезаписывает все предыдущие присваивания этим переменным, включая те, которые были выполнены в блоке цикла for:
for i in range(10):
print(i)
i = 5 # this will not affect the for-loop
# because i will be overwritten with the next
# index in the range
Имена в списке целей не удаляются после завершения цикла, но если последовательность пустая, им вообще не будет присвоено значение циклом. Подсказка: встроенный тип range() представляет собой неизменяемые арифметические последовательности целых чисел. Например, итерация range(3) последовательно возвращает 0, 1, а затем 2.
Изменено в версии 3.11: Звездочки теперь разрешены в списке выражений.
8.4. Оператор try
Оператор try определяет обработчики исключений и/или код очистки для группы операторов:
try_stmt ::= try1_stmt | try2_stmt | try3_stmt
try1_stmt ::= "try" ":" suite
("except" [expression ["as" identifier]] ":" suite)+
["else" ":" suite]
["finally" ":" suite]
try2_stmt ::= "try" ":" suite
("except" "*" expression ["as" identifier] ":" suite)+
["else" ":" suite]
["finally" ":" suite]
try3_stmt ::= "try" ":" suite
"finally" ":" suite
Дополнительную информацию об исключениях можно найти в разделе Исключения, а информацию об использовании оператора raise для генерации исключений — в разделе Оператор raise.
8.4.1. Блок except
Блок(и) except определяют один или несколько обработчиков исключений. Если в блоке try исключений не происходит, никакой обработчик не выполняется. Если исключение происходит в блоке try операторов, начинается поиск обработчика исключений. Этот поиск проверяет блоки except поочерёдно, пока не будет найден блок, соответствующий исключению. Блок except без выражения, если он присутствует, должен быть последним; он соответствует любому исключению. Для блока except с выражением это выражение вычисляется, и блок соответствует исключению, если полученный объект «совместим» с исключением. Объект совместим с исключением, если объект является классом или невиртуальным базовым классом объекта исключения или кортежем, содержащим элемент, являющийся классом или невиртуальным базовым классом объекта исключения.
Если ни один блок except не соответствует исключению, поиск обработчика исключений продолжается в окружающем коде и на стеке вызовов. 1
Если при вычислении выражения в заголовке блока except возникает исключение, исходный поиск обработчика отменяется, и начинается поиск нового исключения в окружающем коде и на стеке вызовов (считается, что весь оператор try вызвал это исключение).
Когда находится соответствующий блок except , исключение присваивается целевому имени после ключевого слова as в этом блоке except, если он присутствует, и выполняется блок операторов этого блока except. Все блоки except должны иметь исполняемый блок. После достижения конца этого блока выполнение продолжается нормально после всего оператора try. (Это означает, что если существуют два вложенных обработчика для одного и того же исключения, и исключение возникает в блоке try внутреннего обработчика, внешний обработчик не обработает исключение.)
После того, как исключение было присвоено с помощью as target, оно очищается в конце блока except . Это как будто
except E as N:
foo
преобразовалось в
except E as N:
try:
foo
finally:
del N
Это означает, что исключение необходимо присвоить другому имени, чтобы иметь возможность обратиться к нему после блока except . Исключения очищаются, потому что, имея отладочную информацию, они образуют цикл ссылок со стековым кадром, сохраняя все локальные переменные в этом кадре живыми до следующего сбора мусора.
Перед выполнением блока операторов блока except исключение сохраняется в модуле sys, где к нему можно обратиться изнутри блока except блока с помощью вызова sys.exception(). При выходе из обработчика исключений исключение, хранящееся в модуле sys, сбрасывается до своего предыдущего значения:
>>> print(sys.exception()) None >>> try: ... raise TypeError ... except: ... print(repr(sys.exception())) ... try: ... raise ValueError ... except: ... print(repr(sys.exception())) ... print(repr(sys.exception())) ... TypeError() ValueError() TypeError() >>> print(sys.exception()) None
8.4.2. Блок except*
Блок except* используется для обработки ExceptionGroupов. Тип исключения для сопоставления интерпретируется так же, как и в случае с except, но в случае групп исключений могут быть частичные совпадения, когда тип соответствует некоторым исключениям в группе. Это означает, что могут выполниться несколько блоков except* , каждый из которых обрабатывает часть группы исключений. Каждый блок выполняется не более одного раза и обрабатывает группу исключений всех соответствующих исключений. Каждое исключение в группе обрабатывается не более чем одним блоком except* , первым, который ему соответствует.
>>> try:
... raise ExceptionGroup("eg",
... [ValueError(1), TypeError(2), OSError(3), OSError(4)])
... except* TypeError as e:
... print(f'caught {type(e)} with nested {e.exceptions}')
... except* OSError as e:
... print(f'caught {type(e)} with nested {e.exceptions}')
...
caught <class 'ExceptionGroup'> with nested (TypeError(2),)
caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4))
+ Exception Group Traceback (most recent call last):
| File "<stdin>", line 2, in <module>
| ExceptionGroup: eg
+-+---------------- 1 ----------------
| ValueError: 1
+------------------------------------
Любые оставшиеся исключения, которые не были обработаны ни одним блоком except* , повторно генерируются в конце, объединённые в группу исключений вместе со всеми исключениями, которые были сгенерированы внутри блоков except* .
С версии 3.11.4, когда вся группа ExceptionGroup обрабатывается и из блока except* поднято только одно исключение, это исключение больше не оборачивается для формирования новой ExceptionGroup.
Если поднятое исключение не является группой исключений и его тип совпадает с одним из блоков except* , оно перехватывается и оборачивается в группу исключений со строкой сообщения по умолчанию.
>>> try:
... raise BlockingIOError
... except* BlockingIOError as e:
... print(repr(e))
...
ExceptionGroup('', (BlockingIOError()))
Блок except* должен иметь соответствующий тип, и этот тип не может быть подклассом BaseExceptionGroup. Невозможно смешивать except и except* в одном операторе try. break, continue и return не могут появиться в блоке except* .
8.4.3. Блок else
Необязательный блок else выполняется, если поток управления выходит из блока try, исключения не было поднято и не был выполнен ни один оператор return, continue или break. Исключения в блоке else не обрабатываются предшествующими блоками except.
8.4.4. Блок finally
Если finally присутствует, он определяет обработчик «очистки». Блок try выполняется, включая любые блоки except и else. Если в любом из блоков возникает исключение, которое не обрабатывается, исключение временно сохраняется. Выполняется блок finally . Если существует сохранённое исключение, оно повторно поднимается в конце блока finally . Если блок finally вызывает другое исключение, сохранённое исключение устанавливается как контекст нового исключения. Если блок finally выполняет оператор return, break или continue, сохранённое исключение отбрасывается:
>>> def f(): ... try: ... 1/0 ... finally: ... return 42 ... >>> f() 42
Информация об исключении недоступна программе во время выполнения блока finally .
Когда оператор return, break или continue выполняется в блоке операторов try оператора try…finally, также выполняется блок finally «по пути выхода».
Значение возврата функции определяется последним оператором return, который был выполнен. Поскольку блок finally всегда выполняется, оператор return , выполненный в блоке finally , всегда будет последним выполненным:
>>> def foo(): ... try: ... return 'try' ... finally: ... return 'finally' ... >>> foo() 'finally'
Изменено в версии 3.8: До Python 3.8 оператор continue был недопустим в блоке finally из-за проблемы с реализацией.
8.5. Оператор with
Оператор with используется для обертывания выполнения блока методами, определенными менеджером контекста (см. раздел Менеджеры контекста оператора With). Это позволяет обобщить распространенные шаблоны использования try…except…finally для удобного повторного использования.
with_stmt ::= "with" ( "(" with_stmt_contents ","? ")" | with_stmt_contents ) ":" suite
with_stmt_contents ::= with_item ("," with_item)*
with_item ::= expression ["as" target]
Выполнение оператора with с одним «элементом» происходит следующим образом:
- Вычисляется выражение контекста (выражение, заданное в
with_item), чтобы получить менеджер контекста. - Загружается метод
__enter__()менеджера контекста для последующего использования. - Загружается метод
__exit__()менеджера контекста для последующего использования. - Вызывается метод
__enter__()менеджера контекста. -
Если в операторе
withбыл указан целевой объект, то возвращаемое значение из__enter__()присваивается ему.Примечание
Оператор
withгарантирует, что если метод__enter__()возвращается без ошибки, то метод__exit__()всегда будет вызван. Таким образом, если ошибка произойдет во время присваивания целевым объектам, она будет обработана так же, как и ошибка, возникшая внутри блока. - Выполняется блок кода.
-
Вызывается метод
__exit__()менеджера контекста. Если выполнение блока было прервано исключением, тип, значение и traceback исключения передаются в качестве аргументов методу__exit__(). В противном случае передаются три аргументаNone.Если выполнение блока было прервано исключением, и возвращаемое значение из метода
__exit__()было false, исключение переиздается. Если возвращаемое значение было true, исключение подавляется, и выполнение продолжается со следующей за операторомwithинструкцией.Если выполнение блока было прервано по какой-либо причине, не связанной с исключением, возвращаемое значение из
__exit__()игнорируется, и выполнение продолжается в обычном месте для такого рода завершения.
Следующий код:
with EXPRESSION as TARGET:
SUITE
семантически эквивалентен:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
При использовании нескольких элементов, менеджеры контекстов обрабатываются как если бы несколько операторов with были вложены:
with A() as a, B() as b:
SUITE
семантически эквивалентно:
with A() as a:
with B() as b:
SUITE
Также можно записывать менеджеры контекста с несколькими элементами на нескольких строках, если элементы заключены в скобки. Например:
with (
A() as a,
B() as b,
):
SUITE
Изменено в версии 3.1: Поддержка нескольких выражений контекста.
Изменено в версии 3.10: Поддержка использования группирующих скобок для разбиения оператора на несколько строк.
8.6. Оператор match
Новый в версии 3.10.
Оператор match используется для сопоставления с образцом. Синтаксис:
match_stmt ::= 'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT subject_expr ::=star_named_expression","star_named_expressions? |named_expressioncase_block ::= 'case' patterns [guard] ":"block
Примечание
В этом разделе для обозначения мягких ключевых слов используются одинарные кавычки.
Сопоставление с образцом принимает образец в качестве входных данных (после case) и значение объекта (после match). Образец (который может содержать подобразцы) сопоставляется со значением объекта. Результаты:
- Успешное или неудачное сопоставление (также называется успехом или неудачей шаблона).
- Возможная привязка сопоставленных значений к имени. Предпосылки для этого рассматриваются ниже.
Ключевые слова match и case являются мягкими ключевыми словами.
См. также
8.6.1. Обзор
Вот обзор логического потока оператора match:
- Вычисляется выражение объекта
subject_exprи получается значение объекта. Если выражение объекта содержит запятую, кортеж создается с использованием стандартных правил. -
Каждый образец в
case_blockпытается сопоставиться со значением объекта. Конкретные правила успеха или неудачи описаны ниже. Попытка сопоставления может также привязать некоторые или все автономные имена в шаблоне. Точные правила привязки шаблонов зависят от типа шаблона и указаны ниже. Привязки имен, выполненные во время успешного сопоставления с образцом, сохраняются после завершения блока и могут быть использованы после оператора match.Примечание
Во время неудачных сопоставлений с образцом некоторые подобразцы могут быть успешными. Не полагайтесь на то, что привязки будут сделаны для неудачного сопоставления. Аналогично, не полагайтесь на то, что переменные останутся неизменными после неудачного сопоставления. Точное поведение зависит от реализации и может меняться. Это целенаправленное решение, позволяющее различным реализациям добавлять оптимизации.
-
Если шаблон соответствует, вычисляется соответствующее условие (если оно присутствует). В этом случае все привязки имен гарантированно выполнены.
- Если условие вычисляется как истинное или отсутствует, выполняется
blockвнутриcase_block. - В противном случае следующая попытка
case_blockвыполняется, как описано выше. - Если нет дополнительных блоков case, оператор match завершается.
- Если условие вычисляется как истинное или отсутствует, выполняется
Примечание
Пользователи, как правило, не должны полагаться на то, что шаблон будет вычисляться. В зависимости от реализации интерпретатор может кешировать значения или использовать другие оптимизации, которые пропускают повторные вычисления.
Пример оператора match:
>>> flag = False
>>> match (100, 200):
... case (100, 300): # Mismatch: 200 != 300
... print('Case 1')
... case (100, 200) if flag: # Successful match, but guard fails
... print('Case 2')
... case (100, y): # Matches and binds y to 200
... print(f'Case 3, y: {y}')
... case _: # Pattern not attempted
... print('Case 4, I match anything!')
...
Case 3, y: 200
В этом случае if flag является условием. Подробнее об этом читайте в следующем разделе.
8.6.2. Условие
guard ::= "if" named_expression
Условие guard (которое является частью case) должно быть истинным, чтобы код внутри блока case выполнялся. Оно имеет вид: if за которым следует выражение.
Логический поток блока case с условием guard:
- Проверить, был ли успешно выполнен шаблон в блоке
case. Если шаблон не соответствует, условиеguardне вычисляется, и проверяется следующий блокcase. -
Если шаблон соответствует, вычислить условие
guard.- Если условие
guardвычисляется как истинное, блок case выбирается. - Если условие
guardвычисляется как ложное, блок case не выбирается. - Если условие
guardвызывает исключение во время вычисления, исключение передается вверх.
- Если условие
Условиям разрешено иметь побочные эффекты, так как они являются выражениями. Вычисление условий должно происходить от первого к последнему блоку case по одному блоку за раз, пропуская блоки case, шаблоны которых не соответствуют всем требованиям. (То есть, вычисление условий должно выполняться в порядке.) Вычисление условий должно прекратиться, как только блок case будет выбран.
8.6.3. Несводимые блоки case
Несводимый блок case — это блок case, который сопоставляет всё. В операторе match может быть не более одного несводимого блока case, и он должен быть последним.
Блок case считается несводимым, если у него нет условия и его шаблон несводимый. Шаблон считается несводимым, если по его синтаксису можно однозначно сказать, что он всегда будет соответствовать. Только следующие шаблоны являются несводимыми:
- Шаблоны AS с несводимой левой частью
- Шаблоны OR содержащие хотя бы один несводимый шаблон
- Шаблоны capture
- Шаблоны wildcard
- скобочные несводимые шаблоны
8.6.4. Шаблоны
Примечание
В этом разделе используются обозначения грамматики, выходящие за рамки стандартного EBNF:
- обозначение
SEP.RULE+является сокращением дляRULE (SEP RULE)* - обозначение
!RULE— сокращение для утверждения отрицательного предпросмотра
Синтаксис верхнего уровня для patterns:
patterns ::= open_sequence_pattern | pattern
pattern ::= as_pattern | or_pattern
closed_pattern ::= | literal_pattern
| capture_pattern
| wildcard_pattern
| value_pattern
| group_pattern
| sequence_pattern
| mapping_pattern
| class_pattern
В описаниях ниже будет содержаться описание «простыми словами» того, что делает шаблон для наглядности (благодаря Раймонда Хеттингера за документ, который вдохновил на большинство описаний). Обратите внимание, что эти описания предназначены только для иллюстрации и могут не отражать реализацию. Кроме того, они не охватывают все допустимые формы.
8.6.4.1. Шаблоны ИЛИ
Шаблон ИЛИ — это два или более шаблонов, разделенных вертикальными чертами |. Синтаксис:
or_pattern ::= "|".closed_pattern+
Только последний подшаблон может быть неопровержимым, и каждый подшаблон должен связывать тот же набор имён, чтобы избежать неоднозначности.
Шаблон ИЛИ по очереди сопоставляет каждый из своих подшаблонов со значением объекта, пока один из них не увенчается успехом. Затем шаблон ИЛИ считается успешным. В противном случае, если ни один из подшаблонов не увенчается успехом, шаблон ИЛИ терпит неудачу.
Простыми словами, P1 | P2 | ... попытается сопоставить P1, если это не удастся, он попытается сопоставить P2, сразу же достигнув успеха, если какой-либо подшаблон достигнет успеха, в противном случае — неудачу.
8.6.4.2. Шаблоны КАК
Шаблон КАК сопоставляет шаблон ИЛИ слева от ключевого слова as с объектом. Синтаксис:
as_pattern ::= or_pattern "as" capture_pattern
Если шаблон ИЛИ терпит неудачу, шаблон КАК также терпит неудачу. В противном случае шаблон КАК привязывает объект к имени справа от ключевого слова as и получает успех. capture_pattern не может быть _.
Простыми словами P as NAME будет соответствовать P, и при успехе он установит NAME = <subject>.
8.6.4.3. Литеральные Шаблоны
Литеральный шаблон соответствует большинству литералей в Python. Синтаксис:
literal_pattern ::=signed_number|signed_number"+" NUMBER |signed_number"-" NUMBER |strings| "None" | "True" | "False" |signed_number: NUMBER | "-" NUMBER
Правило strings и токен NUMBER определены в стандартной грамматике Python. Поддерживаются тройные кавычки. Поддерживаются сырые строки и байтовые строки. f-строки не поддерживаются.
Формы signed_number '+' NUMBER и signed_number '-' NUMBER предназначены для выражения комплексных чисел; они требуют действительного числа слева и мнимого справа. Например, 3 + 4j.
Простыми словами, LITERAL будет успешным только если <subject> == LITERAL. Для одиночных значений None, True и False, используется оператор is.
8.6.4.4. Шаблоны захвата
Шаблон захвата привязывает значение объекта к имени. Синтаксис:
capture_pattern ::= !'_' NAME
Одиночный символ подчёркивания _ не является шаблоном захвата (это то, что выражает !'_'). Вместо этого он обрабатывается как wildcard_pattern.
В данном шаблоне данное имя может быть связано только один раз. Например, case x, x: ... недопустимо, в то время как case [x] | x: ... разрешено.
Шаблоны захвата всегда успешны. Связывание следует правилам области видимости, установленным оператором выражения присваивания в PEP 572; имя становится локальной переменной в ближайшей содержащей функции области, если нет применимого global или nonlocal оператора.
Простыми словами NAME всегда будет успешным и он установит NAME = <subject>.
8.6.4.5. Шаблоны подстановки
Шаблон подстановки всегда успешен (сопоставляется с чем угодно) и не связывает ни одного имени. Синтаксис:
wildcard_pattern ::= '_'
_ — это мягкое ключевое слово внутри любого шаблона, но только внутри шаблонов. Это идентификатор, как обычно, даже внутри match выражений объекта, guard и case блоков.
Простыми словами, _ всегда будет успешным.
8.6.4.6. Шаблоны значений
Шаблон значения представляет собой именованное значение в Python. Синтаксис:
value_pattern ::= attr attr ::= name_or_attr "." NAME name_or_attr ::= attr | NAME
Имя с точками в шаблоне просматривается с использованием стандартных правил разрешения имён Python правила разрешения имён. Шаблон успешен, если найденное значение сравнивается по равенству со значением объекта (с использованием оператора равенства ==).
Простыми словами NAME1.NAME2 будет успешным только если <subject> == NAME1.NAME2
Примечание
Если одно и то же значение встречается несколько раз в одном операторе сопоставления, интерпретатор может кэшировать первое найденное значение и повторно использовать его вместо того, чтобы повторять тот же поиск. Этот кэш строго связан с заданным выполнением заданного оператора сопоставления.
8.6.4.7. Шаблоны групп
Шаблон группы позволяет пользователям добавлять круглые скобки вокруг шаблонов, чтобы подчеркнуть предполагаемую группировку. В противном случае он не имеет дополнительного синтаксиса. Синтаксис:
group_pattern ::= "(" pattern ")"
Простыми словами (P) имеет тот же эффект, что и P.
8.6.4.8. Шаблоны последовательностей
Шаблон последовательности содержит несколько подшаблонов, которые должны быть сопоставлены с элементами последовательности. Синтаксис аналогичен распаковке списка или кортежа.
sequence_pattern ::= "[" [maybe_sequence_pattern] "]"
| "(" [open_sequence_pattern] ")"
open_sequence_pattern ::= maybe_star_pattern "," [maybe_sequence_pattern]
maybe_sequence_pattern ::= ",".maybe_star_pattern+ ","?
maybe_star_pattern ::= star_pattern | pattern
star_pattern ::= "*" (capture_pattern | wildcard_pattern)
Нет разницы, если для шаблонов последовательностей используются круглые или квадратные скобки (т. е. (...) против [...]).
Примечание
Одиночный шаблон в круглых скобках без последующей запятой (например, (3 | 4)) — это шаблон группы. В то время как одиночный шаблон в квадратных скобках (например, [3 | 4]) по-прежнему является шаблоном последовательности.
В шаблоне последовательности может быть не более одного подшаблона со звёздочкой. Подшаблон со звёздочкой может находиться в любом положении. Если подшаблон со звёздочкой отсутствует, шаблон последовательности — это шаблон последовательности фиксированной длины; в противном случае — шаблон последовательности переменной длины.
Следующее — это логический поток сопоставления шаблона последовательности со значением объекта:
- Если значение объекта не является последовательностью 2, шаблон последовательности терпит неудачу.
- Если значение объекта является экземпляром
str,bytesилиbytearray, шаблон последовательности терпит неудачу. -
Следующие шаги зависят от того, является ли шаблон последовательности фиксированной или переменной длины.
Если шаблон последовательности имеет фиксированную длину:
- Если длина последовательности объекта не равна числу подшаблонов, шаблон последовательности терпит неудачу
- Подшаблоны в шаблоне последовательности сопоставляются с соответствующими элементами последовательности объекта слева направо. Сопоставление прекращается, как только подшаблон терпит неудачу. Если все подшаблоны успешно сопоставляются со своим соответствующим элементом, шаблон последовательности получает успех.
В противном случае, если шаблон последовательности имеет переменную длину:
- Если длина последовательности объекта меньше числа подшаблонов без звёздочки, шаблон последовательности терпит неудачу.
- Ведущие подшаблоны без звёздочки сопоставляются с соответствующими элементами, как для последовательностей фиксированной длины.
- Если предыдущий шаг успешен, шаблон со звёздочкой сопоставляет список, образованный оставшимися элементами объекта, исключая оставшиеся элементы, соответствующие подшаблонам без звёздочки, следующие за шаблоном со звёздочкой.
- Остальные подшаблоны без звёздочки сопоставляются с соответствующими элементами объекта, как для последовательности фиксированной длины.
Примечание
Длина последовательности объекта получается с помощью
len()(т. е. через протокол__len__()). Эта длина может быть кэширована интерпретатором аналогичным образом, как и шаблоны значений.
Простыми словами [P1, P2, P3, … , P<N>] соответствует только в том случае, если происходит следующее:
- проверка
<subject>— последовательность len(subject) == <N>-
P1соответствует<subject>[0](обратите внимание, что это соответствие также может связывать имена) -
P2соответствует<subject>[1](обратите внимание, что это соответствие также может связывать имена) - … и так далее для соответствующего шаблона/элемента.
8.6.4.9. Образцы отображений
Образец отображения содержит один или несколько образцов ключ-значение. Синтаксис аналогичен построению словаря. Синтаксис:
mapping_pattern ::= "{" [items_pattern] "}"
items_pattern ::= ",".key_value_pattern+ ","?
key_value_pattern ::= (literal_pattern | value_pattern) ":" pattern
| double_star_pattern
double_star_pattern ::= "**" capture_pattern
В образце отображения может быть не более одного образца с двойной звёздочкой. Образец с двойной звёздочкой должен быть последним подобразцом в образце отображения.
Дублирование ключей в образцах отображения запрещено. Дублирование буквальных ключей вызовет SyntaxError. Два ключа с одинаковым значением, в противном случае, вызовут ValueError во время выполнения.
Следующий логический поток соответствует сопоставлению образца отображения со значением-объектом:
- Если значение-объект не является отображением 3, образец отображения не соответствует.
- Если каждый ключ, указанный в образце отображения, присутствует в отображении-объекте, и образец для каждого ключа соответствует соответствующему элементу отображения-объекта, образец отображения соответствует.
- Если обнаружены дублирующиеся ключи в образце отображения, образец считается невалидным.
SyntaxErrorгенерируется для дублирующих буквальных значений; илиValueError— для именованных ключей с одинаковым значением.
Примечание
Пары ключ-значение сопоставляются с помощью двухаргументного варианта метода get() объекта-отображения. Сопоставленные пары ключ-значение должны уже присутствовать в отображении, а не создаваться динамически с помощью __missing__() или __getitem__().
Простыми словами {KEY1: P1, KEY2: P2, ... } соответствует только если происходит следующее:
- проверка
<subject>является отображением KEY1 in <subject>-
P1соответствует<subject>[KEY1] - … и так далее для соответствующей пары КЛЮЧ/образец.
8.6.4.10. Образцы классов
Образец класса представляет класс и его позиционные и ключевые аргументы (если таковые имеются). Синтаксис:
class_pattern ::= name_or_attr "(" [pattern_arguments ","?] ")"
pattern_arguments ::= positional_patterns ["," keyword_patterns]
| keyword_patterns
positional_patterns ::= ",".pattern+
keyword_patterns ::= ",".keyword_pattern+
keyword_pattern ::= NAME "=" pattern
Один и тот же ключевой аргумент не должен повторяться в образцах классов.
Следующий логический поток соответствует сопоставлению образца класса со значением-объектом:
- Если
name_or_attrне является экземпляром встроенногоtype, генерируетсяTypeError. - Если значение-объект не является экземпляром
name_or_attr(проверка черезisinstance()), образец класса не соответствует. -
Если аргументы образца отсутствуют, образец соответствует. В противном случае, последующие шаги зависят от наличия образцов ключевых или позиционных аргументов.
Для ряда встроенных типов (указанных ниже), принимается один позиционный подобразец, который соответствует всему объекту-субъекту; для этих типов ключевые образцы также работают как и для других типов.
Если присутствуют только ключевые образцы, они обрабатываются следующим образом, по одному:
I. Ключевое слово ищется как атрибут объекта-субъекта.
- Если при этом возникает исключение, отличное от
AttributeError, исключение передаётся вверх. - Если при этом возникает
AttributeError, образец класса не соответствует. - В противном случае, подобразец, связанный с ключевым образцом, сопоставляется со значением атрибута объекта-субъекта. Если это не соответствует, образец класса не соответствует; если это соответствует, сопоставление продолжается для следующего ключевого слова.
II. Если все ключевые образцы соответствуют, образец класса соответствует.
Если присутствуют позиционные образцы, они преобразуются в ключевые образцы с использованием атрибута
__match_args__классаname_or_attrперед сопоставлением:I. Вызывается эквивалент
getattr(cls, "__match_args__", ()).- Если при этом возникает исключение, исключение передаётся вверх.
- Если возвращаемое значение не является кортежем, преобразование завершается неудачей и генерируется
TypeError. - Если позиционных образцов больше, чем
len(cls.__match_args__), генерируетсяTypeError. - В противном случае, позиционный образец
iпреобразуется в ключевой образец, используя__match_args__[i]в качестве ключевого слова.__match_args__[i]должен быть строкой; в противном случае генерируетсяTypeError. - Если присутствуют дублирующиеся ключевые слова, генерируется
TypeError.
- II. После преобразования всех позиционных образцов в ключевые образцы,
-
сопоставление продолжается, как если бы были только ключевые образцы.
Для следующих встроенных типов обработка позиционных подобразцов отличается:
Эти классы принимают один позиционный аргумент, и образец там сопоставляется со всем объектом, а не с атрибутом. Например,
int(0|1)соответствует значению0, но не значению0.0. - Если при этом возникает исключение, отличное от
Простыми словами CLS(P1, attr=P2) соответствует только если происходит следующее:
isinstance(<subject>, CLS)- преобразовать
P1в ключевой образец, используяCLS.__match_args__ -
Для каждого ключевого аргумента
attr=P2:hasattr(<subject>, "attr")-
P2соответствует<subject>.attr
- … и так далее для соответствующей пары ключевой аргумент/образец.
8.7. Определения функций
Определение функции задаёт объект пользовательской функции (см. раздел Иерархия стандартных типов):
funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")"
["->" expression] ":" suite
decorators ::= decorator+
decorator ::= "@" assignment_expression NEWLINE
parameter_list ::= defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
| parameter_list_no_posonly
parameter_list_no_posonly ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
| parameter_list_starargs
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
| "**" parameter [","]
parameter ::= identifier [":" expression]
defparameter ::= parameter ["=" expression]
funcname ::= identifier
Определение функции является исполняемым оператором. Его выполнение связывает имя функции в текущем локальном пространстве имён с объектом функции (обёрткой вокруг исполняемого кода функции). Этот объект функции содержит ссылку на текущее глобальное пространство имён в качестве глобального пространства имён, которое будет использоваться при вызове функции.
Определение функции не выполняет тело функции; оно выполняется только при вызове функции. 4
Определение функции может быть заключено в одну или несколько выражений декоратора. Выражения декоратора вычисляются при определении функции в области видимости, содержащей определение функции. Результат должен быть вызываемым объектом, который вызывается с объектом функции в качестве единственного аргумента. Возвращаемое значение связывается с именем функции вместо объекта функции. Несколько декораторов применяются вложенным образом. Например, следующий код
@f1(arg) @f2 def func(): pass
приблизительно эквивалентен
def func(): pass func = f1(arg)(f2(func))
за исключением того, что исходная функция временно не связывается с именем func.
Изменено в версии 3.9: Функции могут быть декорированы любым допустимым выражением assignment_expression. Ранее грамматика была намного более ограниченной; см. PEP 614 для получения подробной информации.
Когда один или несколько параметров имеют вид параметр = выражение, функция называется функцией с «значениями параметров по умолчанию». Для параметра с значением по умолчанию соответствующий аргумент может быть опущен при вызове, в этом случае подставляется значение параметра по умолчанию. Если параметр имеет значение по умолчанию, все следующие параметры до «*» также должны иметь значение по умолчанию — это синтаксическое ограничение, которое не выражается грамматикой.
Значения параметров по умолчанию вычисляются слева направо при выполнении определения функции. Это означает, что выражение вычисляется один раз при определении функции, и то же «предварительно вычисленное» значение используется для каждого вызова. Это особенно важно понимать, когда значение параметра по умолчанию является изменяемым объектом, таким как список или словарь: если функция изменяет объект (например, добавляет элемент в список), значение параметра по умолчанию фактически изменяется. Это, как правило, не то, что было задумано. Способ обойти это — использовать None в качестве значения по умолчанию и явно проверить его в теле функции, например:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
Семантика вызова функции более подробно описана в разделе Вызовы. При вызове функции всегда присваиваются значения всем параметрам, указанным в списке параметров, либо из позиционных аргументов, либо из именованных аргументов, либо из значений по умолчанию. Если присутствует форма «*identifier», она инициализируется кортежем, получающим любые дополнительные позиционные параметры, по умолчанию — пустым кортежем. Если присутствует форма «**identifier», она инициализируется новым упорядоченным отображением, получающим любые дополнительные именованные аргументы, по умолчанию — новым пустым отображением того же типа. Параметры после «*» или «*identifier» являются именованными параметрами и могут передаваться только с помощью именованных аргументов. Параметры перед «/» являются параметрами только по позиции и могут передаваться только с помощью позиционных аргументов.
Изменено в версии 3.8: Синтаксис параметра функции / может использоваться для обозначения параметров только по позиции. См. PEP 570 для получения подробной информации.
Параметры могут иметь аннотацию вида «: expression» после имени параметра. Любой параметр может иметь аннотацию, даже те, которые имеют вид *identifier или **identifier. Функции могут иметь аннотацию «возврата» вида «-> expression» после списка параметров. Эти аннотации могут быть любыми допустимыми выражениями Python. Наличие аннотаций не меняет семантики функции. Значения аннотаций доступны как значения словаря, ключами которого являются имена параметров, в атрибуте __annotations__ объекта функции. Если используется импорт annotations из __future__, аннотации сохраняются в виде строк во время выполнения, что позволяет отложить их вычисление. В противном случае они вычисляются при выполнении определения функции. В этом случае аннотации могут вычисляться в другом порядке, чем в исходном коде.
Также можно создать анонимные функции (функции, не привязанные к имени), для непосредственного использования в выражениях. Для этого используются выражения lambda, описанные в разделе Lambda-выражения. Обратите внимание, что выражение lambda просто сокращенная запись упрощенного определения функции; функцию, определённую в операторе «def», можно передавать или назначать другому имени, так же как функцию, определённую с помощью lambda-выражения. Форма «def» на самом деле более мощная, так как она позволяет выполнять несколько операторов и аннотаций.
Примечание для программиста: Функции являются объектами первого класса. Оператор «def» , выполненный внутри определения функции, определяет локальную функцию, которую можно возвращать или передавать. Свободные переменные, используемые во вложенной функции, могут получить доступ к локальным переменным функции, содержащей def. Подробности см. в разделе Именование и привязка.
См. также
- PEP 3107 - Аннотации функций
-
Исходное описание аннотаций функций.
- PEP 484 - Типовые подписи
-
Определение стандартного значения для аннотаций: типовые подписи.
- PEP 526 - Синтаксис аннотаций переменных
-
Возможность указывать типовые подписи для объявлений переменных, включая переменные класса и экземпляра.
- PEP 563 - Отложенное вычисление аннотаций
-
Поддержка ссылок вперёд в аннотациях путём сохранения аннотаций в строковом формате во время выполнения вместо немедленного вычисления.
- PEP 318 - Декораторы функций и методов
-
Декораторы функций и методов были введены. Декораторы классов были введены в PEP 3129.
8.8. Определения классов
Определение класса задаёт объект класса (см. раздел Иерархия стандартных типов):
classdef ::= [decorators] "class" classname [inheritance] ":" suite
inheritance ::= "(" [argument_list] ")"
classname ::= identifier
Определение класса — это исполняемая инструкция. Список наследования обычно содержит список базовых классов (см. Метаклассы для более продвинутых случаев), поэтому каждый элемент в списке должен быть объектом класса, который допускает создание подклассов. Классы без списка наследования, по умолчанию, наследуют от базового класса object; следовательно,
class Foo:
pass
эквивалентно
class Foo(object):
pass
Затем тело класса выполняется в новой среде выполнения (см. Имена и привязки), используя новое локальное пространство имён и исходное глобальное пространство имён. (Обычно, тело содержит в основном определения функций.) Когда выполнение тела класса завершается, его среда выполнения удаляется, но его локальное пространство имён сохраняется. 5 Затем создаётся объект класса, используя список наследования для базовых классов и сохранённое локальное пространство имён для словаря атрибутов. Имя класса привязывается к этому объекту класса в исходном локальном пространстве имён.
Порядок определения атрибутов в теле класса сохраняется в новом __dict__ класса. Обратите внимание, что это надёжно только сразу после создания класса и только для классов, которые были определены с помощью синтаксиса определения.
Создание класса можно значительно настроить, используя метаклассы.
Классы также могут быть декорированы: так же, как и при декорировании функций,
@f1(arg) @f2 class Foo: pass
приблизительно эквивалентно
class Foo: pass Foo = f1(arg)(f2(Foo))
Правила оценки выражений декоратора такие же, как и для декораторов функций. Результат затем привязывается к имени класса.
Изменено в версии 3.9: Классы могут быть декорированы любым допустимым assignment_expression. Ранее грамматика была намного более ограниченной; см. PEP 614 для получения подробностей.
Примечание для программиста: Переменные, определённые в определении класса, являются атрибутами класса; они разделяются экземплярами. Атрибуты экземпляра можно задавать в методе с помощью self.name = value. И атрибуты класса, и атрибуты экземпляра доступны через обозначение «self.name», и атрибут экземпляра скрывает атрибут класса с тем же именем, когда он обращается таким образом. Атрибуты класса можно использовать в качестве значений по умолчанию для атрибутов экземпляра, но использование изменяемых значений там может привести к неожиданным результатам. Дескрипторы можно использовать для создания переменных экземпляров с различными деталями реализации.
См. также
8.9. Подпрограммы
Новые в версии 3.5.
8.9.1. Определение подпрограммы
async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")"
["->" expression] ":" suite
Выполнение Python-подпрограмм может быть приостановлено и возобновлено во многих точках (см. подпрограмму). await выражения, async for и async with могут использоваться только в теле подпрограммы.
Функции, определённые с помощью async def синтаксиса, всегда являются подпрограммами, даже если они не содержат await или async ключевые слова.
Использование yield from выражения внутри тела подпрограммы является SyntaxError.
Пример подпрограммы:
async def func(param1, param2):
do_stuff()
await some_coroutine()
Изменено в версии 3.7: await и async теперь являются ключевыми словами; ранее они обрабатывались только как таковые внутри тела подпрограммы.
8.9.2. Оператор async for
async_for_stmt ::= "async" for_stmt
Асинхронный итератор предоставляет метод __aiter__, который напрямую возвращает асинхронный итератор, который может вызывать асинхронный код в своём методе __anext__.
Оператор async for позволяет удобно итерироваться по асинхронным итераторам.
Следующий код:
async for TARGET in ITER:
SUITE
else:
SUITE2
Семантически эквивалентен:
iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True
while running:
try:
TARGET = await type(iter).__anext__(iter)
except StopAsyncIteration:
running = False
else:
SUITE
else:
SUITE2
См. также __aiter__() и __anext__() для деталей.
Использование оператора async for вне тела подпрограммы является SyntaxError.
8.9.3. Оператор async with
async_with_stmt ::= "async" with_stmt
Асинхронный менеджер контекста — это менеджер контекста, способный приостанавливать выполнение в методах enter и exit.
Следующий код:
async with EXPRESSION as TARGET:
SUITE
семантически эквивалентен:
manager = (EXPRESSION)
aenter = type(manager).__aenter__
aexit = type(manager).__aexit__
value = await aenter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not await aexit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
await aexit(manager, None, None, None)
См. также __aenter__() и __aexit__() для деталей.
Использование оператора async with вне тела подпрограммы является SyntaxError.
См. также
- PEP 492 - Подпрограммы с синтаксисом async и await
-
Предложение, которое сделало подпрограммы полноценной самостоятельной концепцией в Python и добавило поддерживающий синтаксис.
Примечания
-
1 -
Исключение передаётся в стек вызовов, если нет
finallyблока, в котором возникает другое исключение. Это новое исключение приводит к потере старого. -
2 -
В шаблонах сопоставления последовательность определяется как одно из следующих:
- класс, унаследованный от
collections.abc.Sequence - класс Python, зарегистрированный как
collections.abc.Sequence - встроенный класс, у которого бит (CPython)
Py_TPFLAGS_SEQUENCEустановлен - класс, унаследованный от любого из вышеперечисленных
Следующие стандартные библиотечные классы являются последовательностями:
Примечание
Значения параметров типа
str,bytes, иbytearrayне соответствуют шаблонам последовательностей. - класс, унаследованный от
-
3 -
В шаблонах сопоставления отображение определяется как одно из следующих:
- класс, унаследованный от
collections.abc.Mapping - класс Python, зарегистрированный как
collections.abc.Mapping - встроенный класс, у которого бит (CPython)
Py_TPFLAGS_MAPPINGустановлен - класс, унаследованный от любого из вышеперечисленных
Стандартные библиотечные классы
dictиtypes.MappingProxyTypeявляются отображениями. - класс, унаследованный от
-
4 -
Строковая литерал, появляющаяся в качестве первого оператора в теле функции, преобразуется в атрибут
__doc__функции и, следовательно, в строку документации функции. -
5 -
Строковая литерал, появляющаяся в качестве первого оператора в теле класса, преобразуется в элемент
__doc__пространства имён, а следовательно, в строку документации класса.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/reference/compound_stmts.html