Функции и их аргументы в Python 3

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

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

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

Функция – это изолированный блок кода, который решает отдельную задачу.

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

Функции также помогают организовать ваш код.

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

Если говорить о принципах программирования, использование функций — это следование принципу DRY (Don’t Repeat Yourself — «не повтоярйся»).

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

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

Определение функции в Python

Базовый синтаксис определения функции выглядит так:

def function_name(parameters):
    function body

Итак, давайте разберемся:

  • def — ключевое слово. Оно сообщает Python, что начинается определение функции.
  • Затем идет имя функции. Оно может быть произвольным (ограничения те же, что и для обозначения переменных).
  • Далее у нас есть пара круглых скобок (). Внутри них могут быть разделенные запятыми параметры. Для параметров могут указываться дефолтные значения. Количество параметров варьируется: может быть один или несколько, а может и вовсе не быть параметров.
  • Затем идет двоеточие :, которое завершает строку определения функции.
  • Дальше идет новая строка, начинающаяся с отступа (4 пробела или одно нажатие клавиши tab).
  • В этой новой строке после отступа начинается тело функции: код действий, которые должна осуществлять функция при вызове.
  • Наконец, в теле функции может быть опциональный оператор return, возвращающий значение вызывающей стороне при выходе из функции.

Имейте в виду, что если вы забудете круглые скобки () или двоеточие :, Python сообщит вам об этом с помощью SyntaxError.

Определение и вызов простой функции в Python

Ниже приведен пример базовой функции. В ней нет оператора return, и никаких параметров она тоже не принимает.

Эта функция просто выводит hello world при каждом вызове.

def hello_world_func():
    print("hello world")

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

Вызывать функцию можно столько раз, сколько вам нужно.

Для вызова функции используется следующий синтаксис:

function_name(arguments)

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

Для вызова функции из нашего примера пишем следующий код:

hello_world_func()

# Результат:
# hello world 

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

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

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

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

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

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

В нашем примере мы указали один параметр — 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!")

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

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

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

[python_ad_block]

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

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"

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

Количество позиционных аргументов имеет значение

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

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

Скажем, у нас есть функция с двумя параметрами:

def hello_to_you(first_name,last_name):
    print(f"Hello, {first_name} {last_name}")

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

def hello_to_you(first_name,last_name):
    print(f"Hello, {first_name} {last_name}")
    

hello_to_you("Timmy")

# Результат:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello_to_you() missing 1 required positional argument: 'last_name'

Если передать три аргумента вместо двух, опять получим ошибку:

def hello_to_you(first_name,last_name):
    print(f"Hello, {first_name} {last_name}")
    

hello_to_you("Timmy","Jones",34)

# Результат:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello_to_you() takes 2 positional arguments but 3 were given

И если вообще не передать аргументов, это тоже вызовет ошибку:

def hello_to_you(first_name,last_name):
    print(f"Hello, {first_name} {last_name}")
    

hello_to_you()

# Результат:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello_to_you() missing 2 required positional arguments: 'first_name' and 'last_name'

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

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

Аргументы должны передаваться в том же порядке, в котором были объявлены параметры при определении функции.

Это работает так же, как присваивание значений переменным.

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

def hello_to_you(first_name,last_name):
    print(f"Hello, {first_name} {last_name}")
    

hello_to_you("Timmy","Jones")
# Выводит в консоль "Hello, Timmy Jones" 
# Это можно визуализировать так:
# first_name = "Timmy"
# last_name = "Jones"

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

def fave_language(name,language):
    print(f"Hello, I am {name} and my favorite programming language is {language}")

    
fave_language("Python","Dionysia")
# Результат:
# Hello, I am Python and my favorite programming language is Dionysia

# Это как если бы вы сделали так:
# name="Python"
# language = "Dionysia"

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

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

Но в Python есть еще и именованные аргументы.

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

Все ключи совпадают с параметрами, указанными при определении функции.

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

def fave_language(name,language):
    print(f"Hello, I am {name} and my favorite programming language is {language}")

    
fave_language(language="Python",name="Dionysia")
#output:
#Hello, I am Dionysia and my favorite programming language is Python

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

То есть, вы могли бы написать код следующим образом, и это не вызвало бы ошибок:

def fave_language(name,language):
    print(f"Hello, I am {name} and my favorite programming language is {language}")

    
fave_language(language="Python",name="Dionysia")
#output:
#Hello, I am Dionysia and my favorite programming language is Python

Но количество передаваемых аргументов имеет значение.

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

def fave_language(name,language):
    print(f"Hello, I am {name} and my favorite programming language is {language}")

    
fave_language("dionysia",language="Python")
#output:
#Hello, I am dionysia and my favorite programming language is Python

В этом случае порядок опять-таки имеет значение.

Позиционные аргументы всегда идут первыми. Все именованные аргументы должны следовать за позиционными. В противном случае будет ошибка:

def fave_language(name,language):
    print(f"Hello, I am {name} and my favorite programming language is {language}")

    
fave_language(language="Python","dionysia")

Как определять параметр со значением по умолчанию

Аргументы функции также могут иметь значения по умолчанию.

Чтобы аргумент функции имел дефолтное значение, нужно назначить это самое значение параметру при определении функции.

Делается это в формате ключ=значение.

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

def fave_language(language="Python"):
    print(f"My favorite  programming language is {language}!")
    
fave_language()
# Выводит в консоль "My favorite  programming language is Python!" 

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

В нашем примере, если не передан аргумент, значением language всегда будет Python.

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

def fave_language(language="python"):
    print(f"My favorite  programming language is {language}!")
    
fave_language("Java")
# Выводит в консоль "My favorite  programming language is Java!" 

В функции может быть и несколько значений по умолчанию.

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

def personal_details(name="Jimmy",age=28,city="Berlin"):
    print(f"I am {name},{age} years old and live in {city}") 
    
# Мы можем вызывать эту функцию так:

personal_details()
# Результат:
# I am Jimmy,28 years old and live in Berlin

personal_details(age=30)
# I am Jimmy,30 years old and live in Berlin

personal_details(city="Athens",name="Ben",age=24)
# I am Ben,24 years old and live in Athens

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

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

def fave_language(name,language="Python"):
    print(f"My name is {name} and my favorite  programming language is {language}!")
    
fave_language("Dionysia")
# Результат:
#"My name is Dionysia and my favorite  programming language is Python!" 

Мы видим, что аргумент со значением по умолчанию language = "Python" является опциональным. Тогда как позиционный аргумент name всегда будет обязательным. Таким образом, если другой язык не передан, по умолчанию всегда будет Python.

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

Вот такой код не сработал бы:

def fave_language(language="Python",name):
    print(f"My name is {name} and my favorite  programming language is {language}!")
    
fave_language("Dionysia")

# Результат:
 File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

От редакции Pythonist. Иногда нельзя предсказать, сколько аргументов получит функция. Чтобы обработать их, используются специальные конструкции *args и **kwargs. Почитать подробнее можно в статье «Что такое *args и **kwargs?».


Заключение

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

Мы также разобрали тему позиционных и именованных аргументов и использование значений аргументов по умолчанию.

Спасибо за прочтение и успехов в написании кода!

Перевод статьи «Python Function Examples – How to Declare and Invoke with Parameters».