Функция – базовая единица кода в любом более-менее серьезном программировании. Да, пока вы учитесь – вы пишете код вроде «result = 2 + 2; print(result)», но в реальных приложениях код измеряется не отдельными операциями, а бизнес-действиями – создать, передать, вывести на экран, запросить, проверить и так далее. Все это удобно пакуется в функции, которые затем объединяются в классы, библиотеки, фреймворки и конечные приложения. Ниже – о том, как функции устроены в Python и как применять их хорошо/красиво/правильно.
Функция – это выполняющий конкретную операцию (на основе переданных аргументов или без них) логически законченный модуль, который имеет четкие рамки в коде и может быть переиспользован при необходимости. Возьмем крайне простой код и разберем все эти слова на его примере:
Структуру и ключевые слова мы рассмотрим позже, но если вы хоть немного знаете английский – здесь не будет ничего сложного: слово def (от define) указывает на создание новой функции с именем «add_5», функция возвращает переданное ей число, предварительно приплюсовав к нему 5. Что здесь можно увидеть:
Функции – крайне мощный инструмент разработки, потому что они позволяют одновременно:
Функции настолько незаменимы, что есть везде: в императивной парадигме в функции (подпрограммы) выносят любой повторяющийся код; в объектно-ориентированной парадигме функции превращаются в методы – действия объектов; в функциональном программировании функция превращается в объект, на котором все программирование и строится.
Функции, которые мы будем рассматривать ниже, можно называть подпрограммами – маленькими программами внутри основной программы. Кроме них, в Python встречаются и другие подвиды функций, основных – 2:
Сейчас мы приведем в качестве примера сложную функцию, на основе которой будем поэтапно разбирать анатомию функций:
def example_function(a, b=10, *args, **kwargs):
result = a + b
if args:
result += sum(args)
if 'multiply' in kwargs:
result *= kwargs['multiply']
if 'return_type' in kwargs and kwargs['return_type'] == 'str':
return f"Результат: {result}"
elif 'return_type' in kwargs and kwargs['return_type'] == 'dict':
return {"result": result}
else:
return result
print(example_function(5))
print(example_function(5, 15))
print(example_function(5, 15, 1, 2, 3))
print(example_function(5, 15, 1, 2, 3, multiply=2))
print(example_function(5, return_type="str"))
print(example_function(5, 15, 1, 2, return_type="dict"))
Функция всегда начинается с ключевого слова «def», за которым через пробел следует имя функции. Сразу после имени функции идут скобки – в них перечисляются параметры. Если параметров нет – скобки остаются пустыми:
def example_function():
Если вы попытаетесь скормить эту строку интерпретатору, то получите ошибку – в теле функции в Python обязательно должно что-то быть. Если сейчас вы не хотите ничего добавлять – используйте ключевое слово «pass», которое служит заглушкой:
def example_function():
pass
А теперь давайте к самому сложному – параметрам и аргументам. Для начала – обязательно разберитесь, чем они отличаются, потому что в любой технической литературе эта разница имеет большой смысл. Итак:
В коде:
def test_func(x):
return x*2
print(test_func(5))
x – это параметр, а 5 – это аргумент. Кстати, print() – тоже функция, так что test_func(5) – это аргумент.
Итак, какими бывают параметры:
def example_function(a):
def example_function(a, b=10):
def example_function(a, b=10, *args):
def example_function(a, b=10, *args, **kwargs):
Теперь разберемся с аргументами – они бывают:
print(example_function(5, 15, 1, 2, 3))
print(example_function(5, 15, 1, 2, 3, multiply=2))
С аргументами, переданными в args и kwargs, можно работать так же, как и с обычными списками/словарями:
if args:
result += sum(args)
if 'multiply' in kwargs:
result *= kwargs['multiply']
Теперь, когда с объявлением функции и входящими данными покончено, вы можете писать код, который будет что-то делать. Но просто сделать что-либо – недостаточно, вам обычно нужно вернуть данные. Делается это ключевым словом return – как только интерпретатор встречает это слово, он возвращает в строку кода, вызвавшую функцию, прописанный в return результат:
return result
В функции можно использовать несколько return – просто помните, что за один вызов функции можно «триггернуть» один return, не больше:
if 'return_type' in kwargs and kwargs['return_type'] == 'str':
return f"Результат: {result}"
elif 'return_type' in kwargs and kwargs['return_type'] == 'dict':
return {"result": result}
else:
return result
Return в функции может и не быть – тогда функция вернет None.
Чтобы написать хорошую функцию, вам нужно придерживаться следующих правил: