Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [ 36 ] 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

10.4.5 Определение функций

С помощью инструкции def Вы можете определить объект-функцию (function, см. раздел 11.4.1):

def func name( param list ): suite

param list - список параметров (через запятую; если параметры записаны с использованием только первой и второй форм, список может содержать завершающую запятую, которая игнорируется) в следующих формах (различные формы можно смешивать, но каждая из них может использоваться только один раз и порядок их следования должен быть именно таким, в котором они перечислены):

paraml [, param2 ...]

Список простых позиционных параметров. Каждый из параметров может

оно является экземпляром класса) или ассоциированного значения (если исключение является строкой) и объекта traceback (см. раздел 11.9.3). Эти же значения сохраняются в sys.exc type, sys.exc value и sys.exc traceback соответственно. Однако их не рекомендуется использовать, так как это небезопасно в многопоточных программах.

Необязательная ветвь else выполняется, если в блоке основной ветви не было сгенерировано исключение. Если при выполнении ветви except или else генерируется исключение, поиск обработчика производится во внешней инструкции try (если такая имеется), а не в текущей.

Вторая форма используется для определения "страховочного" кода:

try: suitel finally: suite2

Сначала выполняется ветвь try (блок suitel ). Если при этом не возникает исключительной ситуации, далее просто выполняется ветвь finally (блок suite2). Если же в блоке suitel генерируется исключение, то оно временно сохраняется, выполняется ветвь finally и сохраненное исключение генерируется снова (поиск обработчика производится во внешней инструкции try, если такая имеется). Если Вы прерываете выполнение блока suite2 инструкцией return, break или continue или генерируя новое исключение, сохраненное исключение будет утрачено (то есть не будет сгенерировано снова).

Ветвь finally выполняется и в том случае, если выход из блока suitel происходит по инструкции return или break. В текущих реализациях использование инструкции continue в основной ветви инструкции try не допускается (ситуация, возможно, изменится в будущих версиях).



быть идентификатором или подсписком параметров в виде (subparaml [, subparam2 ...]) (подсписки аргументов также могут содержать вложенные подсписки).

paraml = exprl [, param2 = expr2...\

Список позиционных аргументов paramN, имеющих значение по умолчанию, получаемое вычислением выражения exprN. Форма записи параметров такая же, как и для первой формы записи аргументов. Выражения exprN вычисляются один раз - при выполнении определения функции, в области видимости, которое содержит определение функции.

* indentifier

Получение произвольного числа позиционных аргументов. Переменной indentifier присваивается кортеж всех позиционных аргументов, которым не соответствует параметры, заданные с использованием первых двух форм.

**indentifier

Получение произвольного количества именованных аргументов. Переменной indentifier присваивается словарь всех именованных аргументов, которым не соответствуют параметры, заданные с использованием первых двух форм.

При каждом выполнении определения функции (инструкции def) создается объект-функция и привязывается к имени func name (идентификатор) в локальном пространстве имен (не рекомендуется использовать в качестве func name идентификатор, который указан в этом блоке в инструкции global - см. раздел 10.3.9). Создаваемый объект-функция содержит ссылку на текущее глобальное пространство имен, которое будет использоваться в качестве глобального пространства имен при вызове функции.

Определение функции не выполняет тело функции (suite) - оно выполняется только при вызове функции. Аргументы, соответствующие параметрам со значением по умолчанию, могут быть опущены. В этом случае подставляется значение по умолчанию.

Синтаксис и семантика вызова функций описана в разделе 10.2.2. При вызове значения присваиваются всем параметрам, указанным в списке: это может быть значение позиционного или именованного аргумента или значение по умолчанию. Параметры, записанные в виде * identifier и ** identifier, если присутствуют, инициализируются пустыми кортежем и словарем соответственно.

Для создания простой анонимной функции вы можете воспользоваться оператором lambda (см. раздел 10.2.7).

Функция (в том числе, и созданная с помощью оператора lambda) не имеет доступа к локальному пространству имен блока, в котором она определена. Чтобы обойти это ограничение, часто используют значения аргументов по умолчанию:

# Возвращает функцию, которая возвращает аргумент,

# увеличенный на n

def make incrementer(n):



def increment(x, n=n):

return x+n return increment

add1 = make incrementer(1) print add1(3) # Выведет 4

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

def add ostrich notice(notices=None): if notices is None:

notices = [] notices.append(

"Просьба страусов не пугать - пол бетонный") return notices

Однако использовать такое поведение для определения статических переменных нежелательно - лучше использовать глобальные переменные модуля или определить класс со специальным методом call () , например:

# Для вспомогательных объектов используем частные

# имена, которые не будут импортироваться с помощью

# from ... import *

MAX KICKS ALLOWED =10 # Число разрешенных пинков

class dog kicker:

def init (self):

# ведет себя как статическая переменная в

# "функции" kick a dog() self.num of kicks = 0

def call (self, num=1):

if self.num of kicks >= MAX KICKS ALLOWED: print "A Вам собаку не жалко?" return

num = min( MAX KICKS ALLOWED-self.num of kicks, num)

self.num of kicks = self.num of kicks+num print "Вы пнули собаку", num, "раз(а)"

# Этот экземпляр можно использовать аналогично функции kick a dog = dog kicker()



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [ 36 ] 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145