Вычисления значения функции python

Функции в Python

Для определения функции нужно всего лишь написать ключевое слово def перед ее именем, а после — поставить двоеточие. Следом идет блок инструкций.

Последняя строка в блоке инструкций может начинаться с return , если нужно вернуть какое-то значение. Если инструкции return нет, тогда по умолчанию функция будет возвращать объект None . Как в этом примере:

i = 0 def increment(): global i i += 1 

Функция инкрементирует глобальную переменную i и возвращает None (по умолчанию).

Вызовы

Для вызова функции, которая возвращает переменную, нужно ввести:

surface = compute_surface(1.) 

Для вызова функции, которая ничего не возвращает:

Еще

Функцию можно записать в одну строку, если блок инструкций представляет собой простое выражение:

Функции могут быть вложенными:

def func1(a, b): def inner_func(x): return x*x*x return inner_func(a) + inner_func(b) 

Функции — это объекты, поэтому их можно присваивать переменным.

Инструкция return

Возврат простого значения

Аргументы можно использовать для изменения ввода и таким образом получать вывод функции. Но куда удобнее использовать инструкцию return , примеры которой уже встречались ранее. Если ее не написать, функция вернет значение None .

Возврат нескольких значений

Пока что функция возвращала только одно значение или не возвращала ничего (объект None). А как насчет нескольких значений? Этого можно добиться с помощью массива. Технически, это все еще один объект. Например:

def stats(data): """данные должны быть списком""" _sum = sum(data) # обратите внимание на подчеркивание, чтобы избежать переименования встроенной функции sum mean = _sum / float(len(data)) # обратите внимание на использование функции float, чтобы избежать деления на целое число variance = sum([(x-mean)**2/len(data) for x in data]) return mean,variance # возвращаем x,y — кортеж! m, v = stats([1, 2, 1]) 

Аргументы и параметры

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

Параметр — это имя в списке параметров в первой строке определения функции. Он получает свое значение при вызове. Аргумент — это реальное значение или ссылка на него, переданное функции при вызове. В этой функции:

x и y — это параметры, а в этой:

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

def compute_surface(radius, pi=3.14159): return pi * radius * radius 

Если использовать необязательный параметр, тогда все, что указаны справа, должны быть параметрами по умолчанию.

Читайте также:  Get error level php

Выходит, что в следующем примере допущена ошибка:

def compute_surface(radius=1, pi): return pi * radius * radius 

Для вызовов это работает похожим образом. Сначала нужно указывать все позиционные аргументы, а только потом необязательные:

S = compute_surface(10, pi=3.14) 

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

S = compute_surface(radius=10, pi=3.14) 

А этот вызов некорректен:

S = compute_surface(pi=3.14, 10) 

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

def compute_surface2(radius=1, pi=3.14159): return pi * radius * radius S = compute_surface2(radius=1, pi=3.14) S = compute_surface2(pi=3.14, radius=10.) S = compute_surface2(radius=10.) 

Можно не указывать ключевые слова, но тогда порядок имеет значение. Он должен соответствовать порядку параметров в определении:

S = compute_surface2(10., 3.14) S = compute_surface2(10.) 

Если ключевые слова не используются, тогда нужно указывать все аргументы:

def f(a=1,b=2, c=3): return a + b + c 

Второй аргумент можно пропустить:

Чтобы обойти эту проблему, можно использовать словарь:

params = 'a':10, 'b':20> S = f(**params) 

Значение по умолчанию оценивается и сохраняется только один раз при определении функции (не при вызове). Следовательно, если значение по умолчанию — это изменяемый объект, например, список или словарь, он будет меняться каждый раз при вызове функции. Чтобы избежать такого поведения, инициализацию нужно проводить внутри функции или использовать неизменяемый объект:

def inplace(x, mutable=[]): mutable.append(x) return mutable res = inplace(1) res = inplace(2) print(inplace(3)) 
def inplace(x, lst=None): if lst is None: lst=[] lst.append() return lst 

Еще один пример изменяемого объекта, значение которого поменялось при вызове:

def change_list(seq): seq[0] = 100 original = [0, 1, 2] change_list(original) original 

Дабы не допустить изменения оригинальной последовательности, нужно передать копию изменяемого объекта:

original = [0, 1, 2] change_list(original[:]) original 

Указание произвольного количества аргументов

Позиционные аргументы

Иногда количество позиционных аргументов может быть переменным. Примерами таких функций могут быть max() и min() . Синтаксис для определения таких функций следующий:

def func(pos_params, *args): block statememt 

При вызове функции нужно вводить команду следующим образом:

Python обрабатывает позиционные аргументы следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает остальные позиционные аргументы в кортеж (*args), который можно использовать в функции.

def add_mean(x, *data): return x + sum(data)/float(len(data)) add_mean(10,0,1,2,-1,0,-1,1,2) 

Если лишние аргументы не указаны, значением по умолчанию будет пустой кортеж.

Произвольное количество аргументов-ключевых слов

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

def func(pos_params, *args, **kwargs): block statememt 

При вызове функции нужно писать так:

func(pos_params, kw1=arg1, kw2=arg2, ...) 

Python обрабатывает аргументы-ключевые слова следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает другие позиционные аргументы в кортеж (*args), который можно использовать в функции (см. предыдущий раздел). В конце концов, он добавляет все лишние аргументы в словарь (**kwargs), который сможет использовать функция.

def print_mean_sequences(**kwargs): def mean(data): return sum(data)/float(len(data)) for k, v in kwargs.items(): print k, mean(v) print_mean_sequences(x=[1,2,3], y=[3,3,0]) 

Важно, что пользователь также может использовать словарь, но перед ним нужно ставить две звездочки (**):

print_mean_sequences(**'x':[1,2,3], 'y':[3,3,0]>) 

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

Документирование функции

Если изучить ее, обнаружатся два скрытых метода (которые начинаются с двух знаков нижнего подчеркивания), среди которых есть __doc__ . Он нужен для настройки документации функции. Документация в Python называется docstring и может быть объединена с функцией следующим образом:

def sum(x, y): """Первая срока - заголовок Затем следует необязательная пустая строка и текст документации. """ return x+y 

Команда docstring должна быть первой инструкцией после объявления функции. Ее потом можно будет извлекать или дополнять:

print(sum.__doc__) sum.__doc__ += "some additional text" 

Методы, функции и атрибуты, связанные с объектами функции

Если поискать доступные для функции атрибуты, то в списке окажутся следующие методы (в Python все является объектом — даже функция):

sum.func_closure sum.func_defaults sum.func_doc sum.func_name sum.func_code sum.func_dict sum.func_globals 

И несколько скрытых методов, функций и атрибутов. Например, можно получить имя функции или модуля, в котором она определена:

>>> sum.__name__ "sum" >>> sum.__module "__main__" 

Есть и другие. Вот те, которые не обсуждались:

sum.__call__ sum.__delattr__ sum.__getattribute__ sum.__setattr__ sum.__class__ sum.__dict__ sum.__globals__ sum.__new__ sum.__sizeof__ sum.__closure__ sum.__hash__ sum.__reduce__ sum.__str__ sum.__code__ sum.__format__ sum.__init__ sum.__reduce_ex__ sum.__subclasshook__ sum.__defaults__ sum.__get__ sum.__repr__ 

Рекурсивные функции

Рекурсия — это не особенность Python. Это общепринятая и часто используемая техника в Computer Science, когда функция вызывает сама себя. Самый известный пример — вычисление факториала n! = n * n — 1 * n -2 * … 2 *1. Зная, что 0! = 1, факториал можно записать следующим образом:

def factorial(n): if n != 0: return n * factorial(n-1) else: return 1 

Другой распространенный пример — определение последовательности Фибоначчи:

def fibbonacci(n): if n >= 2: else: return 1 

Важно, чтобы в ней было была конечная инструкция, иначе она никогда не закончится. Реализация вычисления факториала выше, например, не является надежной. Если указать отрицательное значение, функция будет вызывать себя бесконечно. Нужно написать так:

def factorial(n): assert n > 0 if n != 0: return n * factorial(n-1) else: return 1 

Важно!
Рекурсия позволяет писать простые и элегантные функции, но это не гарантирует эффективность и высокую скорость исполнения.

Если рекурсия содержит баги (например, длится бесконечно), функции может не хватить памяти. Задать максимальное значение рекурсий можно с помощью модуля sys .

Глобальная переменная

Вот уже знакомый пример с глобальной переменной:

i = 0 def increment(): global i i += 1 

Здесь функция увеличивает на 1 значение глобальной переменной i . Это способ изменять глобальную переменную, определенную вне функции. Без него функция не будет знать, что такое переменная i . Ключевое слово global можно вводить в любом месте, но переменную разрешается использовать только после ее объявления.

За редкими исключениями глобальные переменные лучше вообще не использовать.

Присвоение функции переменной

С существующей функцией func синтаксис максимально простой:

Переменным также можно присваивать встроенные функции. Таким образом позже есть возможность вызывать функцию другим именем. Такой подход называется непрямым вызовом функции.

Менять название переменной также разрешается:

def func(x): return x a1 = func a1(10) 

В этом примере a1, a2 и func имеют один и тот же id. Они ссылаются на один объект.

Практический пример — рефакторинг существующего кода. Например, есть функция sq , которая вычисляет квадрат значения:

Позже ее можно переименовать, используя более осмысленное имя. Первый вариант — просто сменить имя. Проблема в том, что если в другом месте кода используется sq , то этот участок не будет работать. Лучше просто добавить следующее выражение:

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

Теперь к ней нельзя получить доступ, а это может стать проблемой. Чтобы вернуть ее обратно, нужно просто удалить переменную:

Анонимная функция: лямбда

Лямбда-функция — это короткая однострочная функция, которой даже не нужно имя давать. Такие выражения содержат лишь одну инструкцию, поэтому, например, if , for и while использовать нельзя. Их также можно присваивать переменным:

В отличие от функций, здесь не используется ключевое слово return . Результат работы и так возвращается.

С помощью type() можно проверить тип:

На практике эти функции редко используются. Это всего лишь элегантный способ записи, когда она содержит одну инструкцию.

power = lambda x=1, y=2: x**y square = power square(5.) 
power = lambda x,y,pow=2: x**pow + y [power(x,2, 3) for x in [0,1,2]] 

Изменяемые аргументы по умолчанию

>>> def foo(x=[]): ... x.append(1) ... print x ... >>> foo() [1] >>> foo() [1, 1] >>> foo() [1, 1, 1] 

Вместо этого нужно использовать значение «не указано» и заменить на изменяемый объект по умолчанию:

>>> def foo(x=None): ... if x is None: ... x = [] ... x.append(1) ... print x >>> foo() [1] >>> foo() [1] 

Источник

Оцените статью