Как работают функции в Пайтон

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

Что такое функция в Пайтон

Функции в языке программирования Пайтон – это специальная конструкция кода, которая создается как отдельный объект, имеет свой блок кода, т.е. тело функции, и выполняет одно законченное действие. Создаются функции в тех случаях, когда необходимо определенную логику программы выполнять несколько раз в разных частях программы. Вызывается работа функции обращением к ее названию и обязательно указываются круглые скобки, они и являются оператором вызова функции.

Всегда функции создаются вверху программы, после импортов, и для создания функции используется ключевая команда – def, от слова definition, т.е. определение.

def имя_функции():
    тело функции

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

Функции могут что-то возвращать, а могут и ничего не возвращать, такие встречаются редко, но есть. Для того, что бы функция что-то вернула, необходимо использовать ключевое слово return, если же нам нужна функция, которая ничего не возвращает, а допустим, выполняет какое-то действие или просто выводит результат в консоль, то достаточно вызвать print(), если выводим в консоль.

Пример функции, которая ничего не возвращает:

def summa_elements():
    a = 5
    b = 7
    print(f"Summa elements {a + b}")

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

Та же функция, которая возвращает результат суммы 2-х чисел:

def summa_elements():
    a = 5
    b = 7
    return a + b

В первом примере мы увидим результат в консоле, если вызовем работу функции, во втором – ничего не увидим, так как мы ничего не принтуем, т.е. print() – нету! Для того, что бы увидеть какой-то резутат, необходимо вызвать print() и в него передать вызов функции summa_elements(), т.е. вот так:

def summa_elements():
    a = 5
    b = 7
    return a + b

print(f"Summa elements {summa_elements()}")

Параметры и агрументы функции, *args, **kwargs

На этом теория о том, как работают функции в Пайтон не заканчивается, необходимо поговорить о параметрах и аргументах функций: наш пример не особо применим где-то, так как значения a и b указываются сразу в функции, что является не очень удобным способом, по хорошему их нужно передавать в функцию, т.е. объявить ранее перед вызовом, в самом вызове передать их как аргументы, а при создании функции их надо принять, как параметры, т.е.:

def summa_elements(a, b):
    return a + b


a = 5
b = 7
print(f"Summa elements {summa_elements(a, b)}")

Да, кстати, между функцией до ее определения и после должно быть путых 2 строки, такие правила PEP8.

Итак, в предыдущем примере мы определили функцию summa_elements и передали в нее 2 аргумента с точки вызова a и b, а приняла она эти параметры, и уже внутри себя с ними выполнила математическое действие и вернула рузультат, т.е. сумму. Важно помнить, что после ключевой команды return ничего не выполняется, никогда! И с помощью return можно остановить выполнение функции.

Как вы уже заметили, функция может принимать 2 параметра, но это не обязательно, может и меньше и больше, например:

def f(x, y, z):
    return x + y + z
result = f(1, 2, 3)
print(result)

До этого момента мы с вами рассматривали аргументы, которые передаются в функцию как обязательные, так если при создании функции написать что она принимает 2 параметра в виде аргументов, а при вызове ее передать один или три, то мы получим исключение, в котором будет говориться о том, что функция принимает 2 параметра, а передаете вы не 2, т.е. сколько аргументов определено, столько и параметров надо передавать, и такой подход называется обязательные параметры!

Существуют еще и необязательные, т.е. они имеют дефолтное значение во время определения функции, и если не передавать ничего, то будут использоваться дефолтные, а если передавать – то будут использоваться именно те, которые передаем! Но есть момент: обязательные должны идти первыми, и только после обязательных пишем необязательные:

def summa_elements(a, b=15):
    return a + b


a = 5
b = 7
print(f"Summa elements {summa_elements(a, b)}") # Ответ 12

Здесь, параметр b является необязательным, так как в определении ему задано значение по умолчанию, т.е. по дефолту b=15. Но если мы его все таки будем передавать, то в функции будет использовано число 7, а не 15.

Пример без передачи:

def summa_elements(a, b=15):
    return a + b


a = 5
print(f"Summa elements {summa_elements(a)}") # Ответ 20

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

Не всегда удобно ослеживать обязательные и необязательные параметры, а бывают случаи, когда их при каждом новом вызове функции может быть и разное количество, и здесь нам поможет оператор “*” звездочка. Мы привыкли что именно звездочка это операция умножения, но в Python это не всегда так, еще этот оператор может распаковывать элементы, которые хранятся в объекте, например:

a = [1, 2, 3]
b = [*a, 4, 5, 6]
print(b) # Ответ [1, 2, 3, 4, 5, 6]

Оператор “*” распаковал список а и добавил его элементы в список b. И это свойство мы можем использовать и в функциях, при передачи в них аргументов, а именно:

def summa_elements(*args):
    print(type(args)) # Вывод: <class 'tuple'>
    return sum(args)


a = 5
b = 10
print(f"Summa elements {summa_elements(a, b)}") # Вывод: Summa elements 15

Итак, мы видим, что при вызове функции передаем в нее 2 аргумента, а принимает она всего лишь один параметр args со звездочкой впереди. Здесь на самом деле не важно, какое название у параметра, это по договоренности мы используем слово args (arguments), там может быть любая переменная, а особое значение имеет оператор “*”, она как раз и распаковывает параметры, и помещает их в args, при чем, это важно – тип данных у этого объекта – tuple, т.е. кортеж.

Итак, мы научились передавать любое количество параметров в функцию через оператор *args, как же быть, если нам надо передать именованные параметры, т.е. что бы при определении функции мы четко понимали, какое значение будет иметь та или иная переменная? Здесь нам придет на помощь оператор из 2-х звездочек, т.е. “**”, и называют его чаще всего **kwargs (keywords argument). С его помощь мы можем передавать в функцию именованные агрументы:

def average(*args, **kwargs):
    print(kwargs)
    print(type(kwargs))
    print(kwargs.values())
    return sum(kwargs.values()) / len(kwargs)


student = {}
print(f"Average mark {average(math = 10, lang =9, physics =8)}")

Но, так как именованные параметры обязательно должны идти после не именованных, перед **kwargs необходимо написать *args, и теперь мы можем передавать в функцию сразу несколько видов параметров!

Лямбда-функции в Python

lambda агрументы: выражение

Лямбда-функции в Python являются анонимными функциями, т.е. не имеют имени и вызвать ее второй раз не получится! Если для создания пользовательской функции используется ключевое слово def, то для создания анонимной функции – lambda:

Аргументов может быть сколько угодно, но выражение только одно!

Применять Lambda функции желательно там, где необходимо использовать объект-функцию, и только 1 раз.

Простая Lambda функция для удваивания значения:

double = lambda x: x*2
print(double(5)) # 10

Если не использовать Lambda, то функция выглядела бы так:

def double(x):
		return x * 2
print(double(5)) # 10

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

Разница очевидна:

  1. Лямбда функция всегда содержит возвращенное выражение;
  2. Не надо передавать параметров;
  3. Не надо использовать return.

Лямбда функция и функция высшего порядка

Мы уже посмотрели, как работают функции в Пайтон, но лямбда функции можно использовать и с функциями высшего порядка, такими как filter() и map().

Например, функция filter() принимает 2 параметра, это ссылку на функцию и итерируемый объект, как она работает можно посмотреть здесь, в нашем примере list:

my_list = [1, 3, 4, 6, 10, 11, 15, 12, 14]
new_list = list(filter(lambda x: (x%2 == 0) , my_list))
print(new_list) # [4, 6, 10, 12, 14]

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: