Одно из ключевых понятий Python – это функция. Под ней подразумевается часть инструкций, которая принимает какое-то значение, совершает с ним определенные операции и возвращает другое. Функции значительно упрощают жизнь программиста, минимизируя количество строк кода и повышая его читаемость. Рассмотрим их подробнее.
Что такое функция?
Предположим, у нас есть набор часто повторяющихся действий. Если бы не было функций, необходимо было бы их прописывать каждый раз, когда нужно их выполнить. А что делать, если в каждом из этих действий еще множество шагов. Код получается огромным, программа требует дополнительные ресурсы компьютера, сам программист может запутаться в этом коде.
А что делать, если программистов несколько? Чтобы решить эту проблему, были придуманы функции. Причем задолго до появления Python. Они позволяют выполнить необходимую последовательность действий буквально с помощью одной строчки кода.
Еще одно преимущество функций – универсальность. Предположим, у нас есть список чисел, и нам надо составить сумму входящих в него элементов.
Без функции бы пришлось каждый раз этот список прописывать заново. А что делать, если он формируется автоматически, программой? Как его достать тогда?
В случае с функциями, возможно просто дать наименование списка в качестве аргумента, и все будет выполнено автоматически. Сейчас более основательно рассмотрим, как работать с функциями.
Определение функции
Давайте сейчас перейдем к четкому образцу использования функции.
def compute_surface(radius):
from math import pi
return pi * radius * radius
Первая команда объявляет функцию. Для этого употребляется def. После этого вносится наименование функции, а в скобках – переменная, служащая аргументом. Аргументы – это значения, какие даются функции. После первой строки кода каждый раз ставится двоеточие. После этого наступает блок инструкций.
Обратите внимание на отступы. Они должны быть такими, как на примере выше.
Далее идут непосредственно те действия, которые необходимо выполнить функции.
Ну и, наконец, последняя строка – это указание того значения, которое должно возвращаться функцией. Это необходимо делать, начиная словом return. Его можно и не указывать. В этом случае возвращается объект none.
Например, функция, возвращающая нулевое значение, объявляется таким образом.
i = 0
def increment():
global i
i += 1
Что делает она? Она увеличивает переменную на единицу. Все, что ей надо – выполнить действие.
Вызов
Осуществление вызова функции – простейшая операция. Если она возвращает что-то, то необходимо ее присвоить той переменной, которая должна содержать это значение.
surface = compute_surface(1)
Если же необходимо выполнить функцию, что попросту проделывает некоторое действие, то достаточно написать имя данной функции с аргументами (или порожними скобками).
increment()
Еще
Необязательно вписывать функцию в виде многих строк кода. Если директива представляет собой несложное выражение, то достаточно одной.
def sum(a, b): return a + b
Также возможно использование одной функции в другой.
def func1(a, b):
def inner_func(x):
return x*x*x
return inner_func(a) + inner_func(b)
Поскольку любая функция по своей природе является объектом, то ее можно присваивать переменной.
Описание инструкции return
Return простого значения
Вывод можно осуществить не только с использованием директивы return. Например, можно прописать изменение переменной в инструкцию. Тем не менее, использование этого ключевого слова гораздо удобнее.
Множественный Return
А что делать, если необходимо сделать так, чтобы функция возвращала больше, чем одно значение? Чтобы выполнить эту задачу, нужно реализовать возврат массива. Это также является одним объектом.
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])
Аргументы и параметры функции
Сперва рассмотрим значние понятий «аргументы» и «параметры»:
- Параметр – это то, что передается в общем виде. То есть, это переменная, которая должна принять значение, когда мы ее используем.
- Аргумент – непосредственно то значение, которое передается.
Для наглядности, приведем следующие строки кода.
def sum(x, y):
return x + y
Здесь x и y – параметры, которые являют собой названия переменных.
А вот если указать в скобках во время использования функции конкретные числа, они уже будут называться аргументами.
Проще говоря, параметры – на этапе объявления функции, а аргументы – на этапе использования.
Позиционные аргументы
Отдельно стоит сказать о позиционных аргументов. Это означает, что функция передает результат сообразно позиции аргументов в скобках.
Давайте теперь рассмотрим следующий фрагмент:
def add(x, y):
return x + y
Если передать аргументы в последовательности 10,20, то функция это прочитает, как x = 10, y = 20.
Это удобно, поскольку все интуитивно понятно, как в математике. Но здесь же мы сталкиваемся с недостатком – что делать, если мы не можем заранее знать, сколько аргументов понадобится.
Переменные аргументы
Это аргументы, количество которых может меняться, но они задаются в виде одного параметра при объявлении функции. Типичный пример – print. Она принимает такое количество аргументов, которое требуется в конкретной ситуации. Причем может быть такое, что у нее вообще не будет аргументов.
Как же сделать такую функцию самостоятельно? Для этого необходимо использовать такой синтаксис.
>>> def f(*args):
… print(type(args))
… print(args)
…
>>> f()
tuple
()
>>> f(1, ‘a’, None, False)
tuple
(1, ‘a’, None, False)
В приведенном выше коде мы в заголовке функции использовали исключительно один параметр args. Обратите внимание, что перед ним мы поставили звездочку. Она сигнализирует о том, что она принимает все аргументы, которые введет пользователь от текущей позиции вплоть до того момента, как он прекратит.
Обратите внимание! Такой аргумент может быть только один в функции.
Если же нужно сделать так, чтобы функции передавались и позиционные, и переменные аргументы, первые должны располагаться в первую очередь. Те аргументы, которые не содержат звездочки в названии, являются обязательными. Например, разберем такой код.
>>> def greet(name, *args):
… for n in (name,) + args:
… print(‘Hello, {}!’.format(n))
…
>>> greet(‘Tom’, ‘Ann’)
Hello, Tom!
Hello, Ann!
>>> greet()
…
TypeError: greet() missing 1 required positional argument: ‘name’
Что мы видим из этого кода?
- Мы использовали один позиционный и один переменный аргумент.
- Позиционный является обязательным. После того, как мы попробовали ввести два имени, программа поздоровалась с Томом и Анной. Но когда мы не ввели ни одного аргумента, выдало ошибку, связанную с тем, что функция требует хотя бы одно имя.
- С помощью комбинации позиционных и переменных аргументов программист может задавать количество обязательных аргументов, но допускать и большее. Это делает программу более гибкой.
Программисты договорились между собой, что переменный аргумент всегда должен называться *args. Это не значит, что нельзя использовать другой. Но это значительно усложняет чтение кода посторонними людьми. Поэтому при объявлении переменной лучше следовать этому правилу.
Можно также использовать значения по умолчанию. В этом случае необходимо в скобках параметров указать название переменной и присвоить сразу ей определенное значение).
Если определенные аргументы задаются заранее, то они также указываются до переменных.
Использование словаря в качестве аргумента
У пользователя также есть возможность применять в качестве аргумента словарь. В этом случае перед ним надо писать **, как на этом примере.
print_mean_sequences(**{‘x’:[1,2,3], ‘y’:[3,3,0]})
Передача коллекции аргументов
Нередко возникает необходимость сначала сформировать несколько аргументов, и уже одним пакетом передать их функции. Типичный пример такой ситуации – аргументы хранятся в файле, и необходимо с помощью программы их оттуда достать. В этом случае также необходимо использовать звездочку в параметре.
Мы используем переменный аргумент, которому передается массив данных.
Приведем пример кода, как это работает.
>>> names = [‘Tom’, ‘Ann’]
>>> greet(*names)
Hello, Tom!
Hello, Ann!
Также можно использовать несколько коллекций в скобках.
>>> greet(
… ‘Bob’, *[‘Mary’, ‘Clair’], ‘Sam’,
… *(‘Henry’, ‘John’)
… )
Hello, Bob!
Hello, Mary!
Hello, Clair!
Hello, Sam!
Hello, Henry!
Hello, John!
Документирование функции
Давайте объявим следующую функцию:
def sum(s,y): return x + y
Посмотрим на нее более детально. В ней есть две функции, каких не видно в данном фрагменте. Чтобы ими воспользоваться, необходимо использовать два знака _ (по одному с каждой стороны). Один из которых – _doc_, и он позволяет настроить документацию.
Возможно ее объединение с функцией. Это дается так.
def sum(x, y):
«»»Первая срока — заголовок
Затем идет опциональная строка и содержимое
документации.
«»»
return x+y
print(sum.__doc__)
sum.__doc__ += «some additional text»
Эта директива должна располагаться еще до того, как функция будет объявлена. После того, как это будет сделано, с ней можно совершать разные операции, такие как дополнение или извлечение.
Таким образом, работа с функциями в Python довольно просто устроена. Главное – понять логику. После этого создавать свои или использовать существующие не составит никакого труда.