Все о функциях высшего порядка в python

Как определять и вызывать функции с параметрами в Python

Пока что мы рассмотрели самый базовый вариант функции. Она лишь выводит что-то в консоль.

Но что, если в функцию нужно передать какие-то дополнительные данные?

Здесь мы используем такие термины, как параметры и аргументы.

Параметры – это именованные заполнители. Они работают как переменные, определенные локально в строке объявления функции.

def hello_to_you(name):
    print("Hello " + name)

В нашем примере мы указали один параметр — .

Для форматирования строки мы могли бы использовать f-строки. Код, приведенный ниже, работает точно так же, как и приведенный выше:

def hello_to_you(name):
    print(f"Hello {name}")

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

def name_and_age(name,age):
    print(f"I am {name} and I am {age} years old!")

Здесь параметры функции — и .

При вызове функции в нее передаются аргументы.

Аргументы — это информация, переданная в функцию. Они представляют собой настоящие значения, соответствующие параметрам, которые были указаны при объявлении функции.

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

Скачать

×

Вызов функции из предыдущего примера и передача аргументов будет выглядеть так:

def hello_to_you(name):
    print(f"Hello {name}")
    
    
hello_to_you("Timmy")
# Результат:
# Hello Timmy

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

def hello_to_you(name):
    print(f"Hello {name}")
    
hello_to_you("Timmy")
hello_to_you("Kristy")
hello_to_you("Jackie")
hello_to_you("Liv")

# Результат:
# "Hello Timmy"
# "Hello Kristy"
# "Hello Jackie"
# "Hello Liv"

Аргументы, которые мы рассматривали до сих пор, называются позиционными. Все позиционные аргументы являются обязательными.

Аргументы

Позиционные

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

Значения в позиционных аргументах подставляются согласно позиции имён аргументов:

Именованные

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

При вызове соответствие будет определяться по именам, а не по позициям аргументов.

Необязательные параметры (параметры по умолчанию)

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

Аргументы переменной длины (args, kwargs)

Когда заранее неизвестно, сколько конкретно аргументов будет передано в функцию, мы пользуемся аргументами переменной длины. Звёздочка «*» перед именем параметра сообщает интерпретатору о том, что количество позиционных аргументов будет переменным:

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

Функции в питоне могут также принимать и переменное количество именованных аргументов. В этом случае перед названием параметра ставится «»:

Здесь kwargs уже заключает аргументы не в кортеж, а в словарь.

Если объект неизменяемый, то он передаётся в функцию по значению. Неизменяемые объекты это:

  • Числовые типы (int, float, complex).
  • Строки (str).
  • Кортежи (tuple).

В Python изменяемые объекты это:

  • Списки (list).
  • Множества (set).
  • Словари (dict).

Будьте внимательны при передаче изменяемых объектов. Одна из частых проблем новичков.

В функциональном программировании существует понятие «функциями с побочными эффектами» — когда функция в процессе своей работы изменяет значения глобальных переменных. По возможности, избегать таких функций.

Возвращаемое значение в функции на Python

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

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

Напишем функцию, которая возвращает отформатированное имя и фамилию

>>> def form_name(last_name, first_name, middle_name):
…     «»»Возвращает отформатированное полное имя»»»
…     full_name = «{last_name} {first_name} {middle_name}»
…     return full_name.

>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)Пушкин Александр Сергеевич

Функция form_name получает в параметрах имя, фамилию и отечество, далее объединяет эти имена и сохраняет их в переменной full_name. Завершив выполнение, функция возвращает управление в точку вызова с помощью команды return, то есть в строку кода, которая вызывала функцию. 

Предположим, что мы не знаем отчество человека, для передачи его фукции параметру middle_name. В связи с этим удобно заранее сделать в функции необязательный аргумент. Присвоим ( middle_name = «» ) пустое значение.

>>> def form_name(last_name, first_name, middle_name=»):
…     «»»Возвращает отформатированное полное имя»»»
…     full_name = «{last_name} {first_name} {middle_name}»
…     return full_name.

>>> poet = form_name(‘пушкин’, ‘александр’)
>>> print(poet)Пушкин Александр
>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)Пушкин Александр Сергеевич

С необязательным аргументом мы не получим ошибку (TypeError: form_name() missing 1 required positional argument: ‘middle_name’) в случае отсутствия на входе данных по аргументу.

3.2. Возвращение словаря

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

>>> def info_person(first_name, last_name):
…     «»»Возвращает словарь с данными о человеке»»»
…     person = {‘first’: first_name, ‘last’: last_name}
…     return person

>>> musician = info_person(‘Freddie’, ‘Mercury’)
>>> print(musician){‘first’: ‘Freddie’, ‘last’: ‘Mercury’}

При вызове функции info_person получает имя и фамилию на входе и помещает их сразу в словарь, с ключами имя и фамилия. Затем с помощью команды return возвращает словарь. В будущем со словарем будет удобнее работать, мы сможем отдельно использовать имя, фамилию или другие аргументы функции.

Required Arguments

Required arguments are the arguments passed to a function in correct positional order. Here, the number of arguments in the function call should match exactly with the function definition.

To call the function printme(), you definitely need to pass one argument, otherwise it gives a syntax error as follows −

#!/usr/bin/python3

# Function definition is here
def printme( str ):
   "This prints a passed string into this function"
   print (str)
   return

# Now you can call printme function
printme()

When the above code is executed, it produces the following result −

Traceback (most recent call last):
   File "test.py", line 11, in <module>
      printme();
TypeError: printme() takes exactly 1 argument (0 given)

Функция в Python

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

Напишем функцию, которая вычисляет квадрат своего аргумента и выводит на экран:

>>> def square(number):
…     «»»Вычисление квадрата числа»»»
…     (number 2)

>>> square(5)25
>>> square(124.45)15487.802500000002

Определение функции начинается с ключевого слова def, за которым следует имя функции — square. Имя функции, как и имена переменных рекомендуется писать с букв нижнего регистра, а в именах, состоящих из нескольких слов, составляющие должны разделяться символами подчеркивания. Далее в круглых скобках записываются параметры (аргументы) функции, разделенные запятыми. Функция square имеет только один аргумент с именем number — значение, возводимое в квадрат. В случае отсутствия параметров у функции пустые круглые скобки обязательны. В конце строки за параметрами всегда ставится двоеточие ().

После двоеточия новая строка должна идти с отступом (4 пробела). Все строки с отступом образуют тело или блок функции. В «Руководстве по стилю кода Python» указано, что первой строкой блока функции должна быть doc-строка, кратко поясняющая назначение функции: «»»Вычисление квадрата числа»»». Сам код в теле функции состоит всего из одной строки (number 2).

Команда squre(5) вызывает функции square() и передает ей значение аргумента, для выполнения команды . Функция возводит число в квадрат и выводит на экран. 

Variable-length Arguments

You may need to process a function for more arguments than you specified while defining the function. These arguments are called variable-length arguments and are not named in the function definition, unlike required and default arguments.

Syntax for a function with non-keyword variable arguments is given below −

def functionname( *var_args_tuple ):
   "function_docstring"
   function_suite
   return 

An asterisk (*) is placed before the variable name that holds the values of all nonkeyword variable arguments. This tuple remains empty if no additional arguments are specified during the function call. Following is a simple example −

#!/usr/bin/python3

# Function definition is here
def printinfo( arg1, *vartuple ):
   "This prints a variable passed arguments"
   print ("Output is: ")
   print (arg1)
   
   for var in vartuple:
      print (var)
   return

# Now you can call printinfo function
printinfo( 10 )
printinfo( 70, 60, 50 )

When the above code is executed, it produces the following result −

Output is:
10
Output is:
70
60
50

Аргументы ключевого слова(** kwargs)

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

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

Рассмотрим следующие примеры.

Пример 1.

#function func is called with the name and message as the keyword arguments  
def func(name,message):  
    print("printing the message with",name,"and ",message)  
    
    #name and message is copied with the values John and hello respectively  
    func(name = "John",message="hello") 

Выход:

Пример 2. С указанием значений в другом порядке при вызове.

#The function simple_interest(p, t, r) is called with the keyword arguments the order of arguments doesn't matter in this case  
def simple_interest(p,t,r):  
    return(p*t*r)/100  
print("Simple Interest: ",simple_interest(t=10,r=10,p=1900))   

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

Рассмотрим следующий пример.

Пример 3.

#The function simple_interest(p, t, r) is called with the keyword arguments.   
def simple_interest(p,t,r):  
    return(p*t*r)/100  

# doesn't find the exact match of the name of the arguments(keywords)    
print("Simple Interest: ",simple_interest(time=10,rate=10,principle=1900)) 

Выход:

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

Рассмотрим следующие примеры.

Пример 4.

def func(name1,message,name2):  
    print("printing the message with",name1,",",message,",and",name2)  
#the first argument is not the keyword argument  
func("John",message="hello",name2="David") 

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

Пример 5.

def func(name1,message,name2): 
    print("printing the message with",name1,",",message,",and",name2)  
func("John",message="hello","David")      

Выход:
Python предоставляет возможность передавать несколько аргументов ключевого слова, которые могут быть представлены как ** kwargs. Похож на * args, но сохраняет аргумент в формате словаря. Этот тип аргументов полезен, когда мы не знаем заранее количество аргументов.

Рассмотрим следующий пример:

Пример 6. Многие аргументы используют аргумент ключевого слова.

def food(**kwargs):
    print(kwargs)
food(a="Apple")
food(fruits="Orange", Vagitables="Carrot")

Выход:

{'a': 'Apple'}
{'fruits': 'Orange', 'Vagitables': 'Carrot'}

Важность функций

Абстракция

Человек бежит, машина едет, корабль плывёт, а самолёт летит. Всё это — объекты реального мира, которые выполняют однотипные действия. В данном случае, они перемещаются во времени и пространстве. Мы можем абстрагироваться от их природы, и рассматривать эти объекты с точки зрения того, какое расстояние они преодолели, и сколько времени на это ушло.

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

Нам не важно, кто совершает движение: и для человека и для самолёта средняя скорость будет рассчитываться одинаково

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

Возможность повторного использования

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

Например, при работе с массивами чисел, вам нужно часто их сортировать. Вместо того чтобы реализовать простой алгоритм сортировки (или использовать встроенную функцию), вам пришлось бы каждый раз перепечатывать тело этой или похожей функции:

Всего 10 таких сортировок, и привет, лишние 60 строк кода.

Модульность

Разбитие больших и сложных процессов на простые составляющие — важная часть, как кодинга, так и реальной жизни. В повседневности мы занимаемся этим неосознанно. Когда убираемся в квартире, мы пылесосим, моем полы и окна, очищаем поверхности от пыли и наводим блеск на всё блестящее. Всё это — составляющие одного большого процесса под названием «уборка», но каждую из них также можно разбить на более простые подпроцессы.

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

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

Без применения модульности получится сплошная последовательность инструкций:

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

Это и называется модульностью.

Пространство имен

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

Пример из жизни: в ВУЗе учатся два человека с совпадающими ФИО. Их нужно как-то различать. Если сделать пространствами имён группы этих студентов, то проблема будет решена. В рамках своей группы ФИО этих студентов будут уникальными.

Характеристики списков

Список имеет следующие характеристики:

  • Списки упорядочены.
  • Доступ к элементу списка можно получить по индексу.
  • Списки являются изменяемыми типами.
  • Список может хранить количество различных элементов.

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

 
a =  
b =  
a ==b 

Выход:

False 

Оба списка состояли из одних и тех же элементов, но второй список изменил позицию индекса 5-го элемента, что нарушает порядок списков. При сравнении списков возвращается false.

Списки поддерживают порядок элементов на протяжении всего существования. Вот почему это упорядоченный набор объектов.

 
a =  
b =  
a == b 

Выход:

True 

Давайте подробно рассмотрим пример списка.

 
emp =     
Dep1 =  
Dep2 =    
HOD_CS =    
HOD_IT =    
print("printing employee data...")   
print("Name : %s, ID: %d, Country: %s"%(emp,emp,emp))   
print("printing departments...")  
print("Department 1:\nName: %s, ID: %d\nDepartment 2:\nName: %s, ID: %s"%(Dep1,Dep2,Dep2,Dep2))   
print("HOD Details ....")   
print("CS HOD Name: %s, Id: %d"%(HOD_CS,HOD_CS))   
print("IT HOD Name: %s, Id: %d"%(HOD_IT,HOD_IT))   
print(type(emp),type(Dep1),type(Dep2),type(HOD_CS),type(HOD_IT)) 

Выход:

printing employee data... 
Name : John, ID: 102, Country: USA 
printing departments... 
Department 1: 
Name: CS, ID: 11 
Department 2: 
Name: IT, ID: 11 
HOD Details .... 
CS HOD Name: Mr. Holding, Id: 10 
IT HOD Name: Mr. Bewon, Id: 11 
<class 'list'> <class 'list'> <class 'list'> <class 'list'> <class 'list'> 

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

Обратите внимание на приведенный выше код, чтобы лучше понять концепцию списка

Операторы оцениваются слева направо

Давайте посмотрим на пример, где у нас есть несколько логических операторов. Мы не смешиваем разные типы операторов в Python, поэтому приоритет операторов не будет очевиден и будет легче объяснить результат.

Мы также переопределим функцию __bool __() для вывода значения «id».

def my_bool(data):
    print('Data bool method called, id =', data.id)
    return True if data.id > 0 else False


Data.__bool__ = my_bool

d1 = Data(10)
d2 = Data(-20)
d3 = Data(20)

# evaluated from left to right, confirmed from the __bool__() print statement
if d1 and d2 or d3:
    print('At least one of them have a positive id.')

Вывод:

Data bool method called, id = 10
Data bool method called, id = -20
Data bool method called, id = 20
At least one of them have a positive id.

Обратите внимание, что логическое значение сначала вычисляется для d1, тем самым подтверждая, что выполнение происходит слева направо

Keyword Arguments

Keyword arguments are related to the function calls. When you use keyword arguments in a function call, the caller identifies the arguments by the parameter name.

This allows you to skip arguments or place them out of order because the Python interpreter is able to use the keywords provided to match the values with parameters. You can also make keyword calls to the printme() function in the following ways −

#!/usr/bin/python3

# Function definition is here
def printme( str ):
   "This prints a passed string into this function"
   print (str)
   return

# Now you can call printme function
printme( str = "My string")

When the above code is executed, it produces the following result −

My string

The following example gives a clearer picture. Note that the order of parameters does not matter.

#!/usr/bin/python3

# Function definition is here
def printinfo( name, age ):
   "This prints a passed info into this function"
   print ("Name: ", name)
   print ("Age ", age)
   return

# Now you can call printinfo function
printinfo( age = 50, name = "miki" )

When the above code is executed, it produces the following result −

Name:  miki
Age  50

Scope and Lifetime of variables

Scope of a variable is the portion of a program where the variable is recognized. Parameters and variables defined inside a function are not visible from outside the function. Hence, they have a local scope.

The lifetime of a variable is the period throughout which the variable exists in the memory. The lifetime of variables inside a function is as long as the function executes.

They are destroyed once we return from the function. Hence, a function does not remember the value of a variable from its previous calls.

Here is an example to illustrate the scope of a variable inside a function.

Output

Value inside function: 10
Value outside function: 20

Here, we can see that the value of x is 20 initially. Even though the function changed the value of x to 10, it did not affect the value outside the function.

This is because the variable x inside the function is different (local to the function) from the one outside. Although they have the same names, they are two different variables with different scopes.

On the other hand, variables outside of the function are visible from inside. They have a global scope.

We can read these values from inside the function but cannot change (write) them. In order to modify the value of variables outside the function, they must be declared as global variables using the keyword .

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

В Python существует возможность возвращать из функции несколько значений.

Вот простой пример:

def f():
    a = 5
    b = 6
    c = 7
    return a, b, c
var1, var2, var3 = f()

print("var1={0} var2={1} var3={2}".format(var1, var2, var3))

Результат:

var1=5 var2=6 var3=7

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

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

Этот пример можно было бы записать и так:

def f():
    a = 5
    b = 6
    c = 7
    return a, b, c
return_value = f()

print(return_value)

Результат:

(5, 6, 7)

В таком случае return_value было бы кортежем, содержащим все три возвращенные переменные.

Иногда разумнее возвращать несколько значений не в виде кортежа, а в виде словаря:

def f():
    a = 5
    b = 6
    c = 7
    return {'a' : a, 'b' : b, 'c' : c}

return_value = f()

print(return_value)

Результат:

{'a': 5, 'b': 6, 'c': 7}

Keyword arguments

Keyword arguments are related to the function calls. When you use keyword arguments in a function call, the caller identifies the arguments by the parameter name.

This allows you to skip arguments or place them out of order because the Python interpreter is able to use the keywords provided to match the values with parameters. You can also make keyword calls to the printme() function in the following ways −

#!/usr/bin/python

# Function definition is here
def printme( str ):
   "This prints a passed string into this function"
   print str
   return;

# Now you can call printme function
printme( str = "My string")

When the above code is executed, it produces the following result −

My string

The following example gives more clear picture. Note that the order of parameters does not matter.

#!/usr/bin/python

# Function definition is here
def printinfo( name, age ):
   "This prints a passed info into this function"
   print "Name: ", name
   print "Age ", age
   return;

# Now you can call printinfo function
printinfo( age=50, name="miki" )

When the above code is executed, it produces the following result −

Name:  miki
Age  50

Создаем калькулятор на Python

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

# This function adds two numbers 
def add(x, y):
   return x + y
 
# This function subtracts two numbers 
def subtract(x, y):
   return x - y
 
# This function multiplies two numbers
def multiply(x, y):
   return x * y
 
# This function divides two numbers
def divide(x, y):
   return x / y
 
print("Select operation.")
print("1.Add")
print("2.Subtract")
print("3.Multiply")
print("4.Divide")
 
# Take input from the user 
choice = input("Enter choice(1/2/3/4):")
 
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
 
if choice == '1':
   print(num1,"+",num2,"=", add(num1,num2))
 
elif choice == '2':
   print(num1,"-",num2,"=", subtract(num1,num2))
 
elif choice == '3':
   print(num1,"*",num2,"=", multiply(num1,num2))
 
elif choice == '4':
   print(num1,"/",num2,"=", divide(num1,num2))
else:
   print("Invalid input")

В результате получим следующее:

Output

Select operation.
1.Add
2.Subtract
3.Multiply
4.Divide
Enter choice(1/2/3/4): 3
Enter first number: 15
Enter second number: 14
15 * 14 = 210

Что такое функция в Python?

Функции в Python – это организованный блок многократно используемого кода, который можно вызывать при необходимости.

Функция содержит набор программных операторов, заключенных в {}. Функцию можно вызывать несколько раз, чтобы обеспечить возможность повторного использования и модульность программы Python.

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

Python предоставляет нам различные встроенные функции, такие как range() или print(). Пользователь также может создавать свои функции, которые можно назвать пользовательскими функциями.

В основном есть два типа функций:

  • Функции, определяемые пользователем. Определяются пользователем для выполнения конкретной задачи.
  • Встроенные функции. Это те функции, которые предварительно определены в Python.

В этом руководстве мы обсудим функции, определяемые пользователем.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector