The Python Language Reference / Справочник по языку Python: 7. Compound statements

Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

Инструкция «<code>with</code>» используется для “оборачивания” исполнения блока методами, определёнными менеджером контекста (смотрите раздел “Менеджеры контекста инструкции «<code>with</code>» ” ) . Это позволяет общим схемам использования «<code>try...except...finally</code>» быть инкапсулированными для удобного повторного использования.

Hittih 22.11.11 в 15:06

0

«<code>with_stmt ::= "with" with_item ("," with_item)* ":" suite</code>»

Hittih 22.11.11 в 15:16

0

«<code>with_item ::= expression ["as" target]</code>»

Hittih 22.11.11 в 15:17

0

Исполнение инструкции «<code>with</code>» с одним “элементом” происходит так:

Hittih 22.11.11 в 15:23

0

Выражение контекста («<code>with_item</code>») вычисляется, чтобы получить менеджер контекста.

Hittih 22.11.11 в 15:46

0

Вызывается метод «<code>__enter__()</code>» этого менеджера контекста.

Hittih 22.11.11 в 15:47

0

Если присутствует цель назначения («<code>target</code>») , то возвращаемое от «<code>__enter__()</code>» значение назначается этой цели.

Hittih 22.11.11 в 15:58

0

Замечание

Hittih 22.11.11 в 16:01

0

Инструкция «<code>with</code>» гарантирует, что если метод «<code>__enter__()</code>» выполняется без ошибки, то обязательно будет вызван «<code>__exit__()</code>» . Таким образом, если ошибка происходит в течение назначения списку целей, то на этом этапе она уже́ будет воспринята как ошибка внутри блока «<code>with</code>» . Смотрите шаг 5 ниже.

Hittih 24.11.11 в 03:31

0

Исполняется блок кода.

Hittih 22.11.11 в 16:02

0

Вызывается метод «<code>__exit__()</code>» менеджера контекста. Если какое-либо исключение приводит к выходу из блока, то тип, значение и стек вызовов этого исключения передаются в качестве аргументов в «<code>__exit__()</code>» – иначе передаются три аргумента «<code>None</code>» .

Hittih 24.11.11 в 03:49

0

Если выход из блока был из-за исключения, и возвращённое методом «<code>__exit__()</code>» значение было “ложь” , то это исключение перевызывается. Если же возвращённое значение было “истина” , то это исключение отменяется, и исполнение продолжается с инструкции следующей за блоком инструкции «<code>with</code>» .

Hittih 24.11.11 в 04:00

0

Если выход из блока был по любой другой причине, то возвращённое методом «<code>__exit__()</code>» значение игнорируется, и исполнение продолжается обычным образом.

Hittih 24.11.11 в 04:06

0

Если у «<code>with</code>» более одного элемента, то это обрабатывается как если бы соответствующие блоки находились один внутри другого :

Hittih 24.11.11 в 04:11

0

<code>with A() as a, B() as b:
    suite</code>

Hittih 22.11.11 в 16:05

0

является эквивалентом

Hittih 22.11.11 в 16:34

0

<code>with A() as a:
    with B() as b:
        suite</code>

Hittih 22.11.11 в 16:07

0

Изменилось в версии 3.1 : поддержка множественных выражений контекста.

Hittih 24.11.11 в 18:33

0

Смотрите также

Hittih 24.11.11 в 18:34

0

PEP 0343 – Инструкция «<code>with</code>»

Hittih 24.11.11 в 18:35

0

Спецификация, объяснения и примеры по Питоновской инструкции «<code>with</code>» .

Hittih 24.11.11 в 18:42

0

7.6. Функции

Hittih 24.11.11 в 18:54

0

7.6. Задание функций

Hittih 24.11.11 в 18:58

0

Код, задающий функцию, создаёт объект пользовательской функции (смотри́те раздел “Иерархия стандартных типов” ) :

Hittih 24.11.11 в 19:07

0

<code>funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite
decorators     ::= decorator+
decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
dotted_name    ::= identifier ("." identifier)*
parameter_list ::= (defparameter ",")*
                   ( "*" [parameter] ("," defparameter)*
                   [, "**" parameter]
                   | "**" parameter
                   | defparameter [","] )
parameter      ::= identifier [":" expression]
defparameter   ::= parameter ["=" expression]
funcname       ::= identifier</code>

Hittih 22.11.11 в 16:12

0

Код, задающий функцию, является исполнимой инструкцией. Его исполнение связывает заданное имя в текущей локальной области имён с объектом функции (в котором содержится исполнимый код функции) . Этот объект функции содержит ссылку на текущую глобальную область имён, и она будет использоваться в качестве глобальной во время вызова этой функции.

Hittih 24.11.11 в 19:24

0

Код, задающий функцию, не исполняет тело этой функции – оно будет исполняться, когда функция будет вызвана.

Hittih 24.11.11 в 19:55

0

Запись текстовой константы, идущая как первая инструкция внутри тела функции, преобразуется в атрибут «<code>__doc__</code>» этой функции и таким образом становится текстом документации этой функции.

Hittih 24.11.11 в 20:01

0

Код, задающий функцию, может подвергаться действию одного или нескольких выражений “декораторов” . “Декоратор” исполняется после того, как соответствующая функция уже́ определена, в той же области видимости, в которой содержится код, задающий эту функцию. Результат исполнения выражения “декоратора” должен быть вызываемым объектом, который вызывается, с данной функцией в качестве единственного аргумента. Возвращаемый объект назначается имени данной функции вместо прежнего объекта-функции. Множественные “декораторы” применяются поочерёдно, в порядке близости к функции (в стиле вложенности) . Например, следующий код

Hittih 24.11.11 в 21:01

0

<code>@f1(arg)
@f2
def func(): pass</code>

Hittih 22.11.11 в 16:25

0

является эквивалентом

Hittih 22.11.11 в 16:27

0

<code>def func(): pass
func = f1(arg)(f2(func))</code>

Hittih 22.11.11 в 16:26

0

Функция хранит значения по-умолчанию для тех параметров, которые имеют форму <code>parameter = expression</code> . Для таких параметров при вызове функции соответствующее им значение может быть пропущено – в этом случае будет подставлено значение по-умолчанию этого параметра. Если некоторый параметр в описании указан со значением по-умолчанию, то все остальные параметры до «<code>*</code>» обязаны тоже иметь значение по-умолчанию.

Hittih 12.12.11 в 11:09

0

Значения параметров по-умолчанию вычисляются, когда исполняется определение функции. Это означает, что выражение вычисляется один раз, когда функция определяется, и одно и то же “предварительно вычисленное” значение используется для каждого вызова. Это особенно важно понять, когда параметр по-умолчанию является изменяемым объектом (например списком или словарём) : если функция изменяет этот объект (например, путем добавления элемента в список) , то это значение по-умолчанию останется изменённым. Как правило, это не то, что было задумано. Способом обойти это является использование «<code>None</code>» в качестве значения по-умолчанию, и явная проверка этого параметра в теле функции, например:

Hittih 12.12.11 в 11:06

0

<code>def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin</code>

Hittih 22.11.11 в 16:32

0

Семантика вызова функции описана более подробно в разделе «calls» . Вызов функции всегда присваивает значения всем параметрам, упомянутым в списке параметров в определении, либо от переданных позиционных аргументов, либо от переданных именованных аргументов, либо от значений по умолчанию. Если присутствует форма “*identifier” , то она инициализируется кортежем, содержащим все лишние позиционные параметры, а при отсутствии таковых – пустым кортежем. Если присутствует форма “**identifier” , то она инициализируется новый словарём, содержащим все лишние именованные аргументы, а при отсутствии таковых – новым пустым словарём. Параметры после “*” или “*identifier” могут быть только именованными параметрами и могут быть переданы только через именованные параметры.

Hittih 12.12.11 в 12:08

0

Параметры могут иметь описания в форме “: expression” после имени параметра. Любой параметр может иметь описание, даже те, которые в форме “*identifier” или “**identifier” . Функции могут иметь описание возвращаемого результата в форме “-> expression” в позиции после списка параметров. Эти описания могут быть любыми допустимыми выражениями Питона, они вычисляются при исполнении определения функции. Описания могут быть вычислены в другом порядке, чем они появляются в исходном коде. Наличие описаний не меняет семантику функции. Значения описаний доступны в виде значений словаря в атрибуте «__annotations__» данной функции, с именем нужного параметра в качестве ключа.

Hittih 12.12.11 в 12:34

0

Кроме того, можно создавать анонимные функции (функции, не связанные с именем), для непосредственного использования по месту создания внутри выражения. Для этого используются лямбда-формы – это практически синоним понятия “упрощенное определение функции” – их описание в разделе Лямбды. Функцию, определенную инструкцией «<code>def</code>» можно передавать или назначать другому имени так же, как и функцию, определенную лямбда-формой. Форма «<code>def</code>» вообще-то имеет больше возможностей, например, позволяет выполнять несколько инструкций и иметь описания.

Hittih 12.12.11 в 19:23

0

Замечание: Функции являются объектами первого класса. Форма «<code>def</code>» выполняемая внутри определения другой функции – создаёт локальную функцию, которая может быть внешнею функцией возвращена в качестве результата или передана куда-либо. Свободные имена, используемые во вложенной функции, могут указывать на локальные переменные внешней функции. Смотрите детали в разделе “Naming and binding”.

Hittih 12.12.11 в 20:02

0

Создание классов

Hittih 12.12.11 в 20:06

0

“Определение” класса создаёт объект-класс (смотрите раздел “The standard type hierarchy” ) :

Hittih 12.12.11 в 20:10

0

<code>classdef    ::= [decorators] "class" classname [inheritance] ":" suite
inheritance ::= "(" [argument_list [","] | comprehension] ")"
classname   ::= identifier</code>

Hittih 22.11.11 в 16:37

0

Код, задающий класс (“определение” класса) , является исполнимой инструкцией. Сначала, если имеется, вычисляется список наследуемых базовых классов (смотри́те подробности в “Customizing class creation” ) . Каждый элемент в этом списке должен давать в результате объект-класс, такой, который допускает создание производного класса. Классы без списка базовых классов – по-умолчанию наследуются от базового объекта:

Hittih 16.12.11 в 17:04

0

<code>class Foo:
    pass</code>

Hittih 22.11.11 в 17:13

0

является эквивалентом

Hittih 22.11.11 в 17:12

0

<code>class Foo(object):
    pass</code>

Hittih 22.11.11 в 17:11

0

Затем основной класс исполняется в новом кадре исполнения (смотри́те раздел “Naming and binding” ) с использованием новосозданной локальной области имён и исходной глобальной области имён. (Обычно код класса содержит только “определения” функций. ) Текстовый объект, идущий с первой строки содержания кода класса, преобразуется в элемент с именем “__doc__” в данной локальной области и, таким образом становится “документацией” этого класса. [4] Когда код класса завершён, его кадр исполнения удаляется, а его локальная область имён сохраняется. Затем создаётся объект-класс с использованием списка наследования для базовых классов, а полученная ранее область имён становится словарём атрибутов класса. Затем полученный объект-класс назначается указанному имени в исходной области имён.

Hittih 16.12.11 в 14:46

0

[4] Текстовый объект, идущий с первой строки содержания кода класса, преобразуется в элемент с именем “__doc__” в данной локальной области и, таким образом становится “документацией” этого класса.

Hittih 16.12.11 в 14:47

0

Создание классов может быть глубоко настроено с помощью метаклассов.

Hittih 16.12.11 в 14:59

0

Классы могут быть “декорированы” , таким же образом как и функции:

Hittih 16.12.11 в 14:56

0

<code>@f1(arg)
@f2
class Foo: pass</code>

Hittih 22.11.11 в 17:05

0
Минутку...

← Предыдущая страница

Следующая страница →