Теория урока

13.7. Аргументы и параметры функций, операторы * и ** в Python

Оглавление урока

Аргументы и параметры

В предыдущем уроке мы разобрались с замыканиями и оператором nonlocal в Python. Сейчас будем разбираться с аргументами и параметрами функций. В этом уроке узнаем, как отправлять функциям объекты в виде входных данных – передача аргументов. Также узнаем об операторах * и ** кое-что новое и это не про умножение и возведение в степень. Аргументы и параметры часто используют как синонимы. Но давайте определим эти понятия:

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

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

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

Пример
def sum(a, b):
    pass

С оператором pass вы уже знакомились в уроке 10.3. В данном примере sum – имя функции. Переменные a и b – обязательные параметры. Теперь рассмотрим пример с необязательными параметрами:

Пример
def sum(a = 0, b = 0):
    pass

В примере выше параметры a и b имеют значения по умолчанию. Теперь о том, как передавать аргументы в функцию. Пример:

Пример
def sum(a = 0, b = 0):
    print(a + b)

sum(5, 3) # a = 5, b = 3
sum(5) # a = 5, b = 0
sum(b = 5) # a = 0, b = 5
sum() # a = 0, b = 0

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

Пример
sum(1, 2) # позиционные аргументы
sum(a = 1, b = 2) # ключевые аргументы
sum(b = 2, a = 1) # ключевые аргументы

Параметры необязательно должны быть все обязательные или необязательные – можно мешать:

Пример
def sum(a, b = 0):
    print(a + b)

sum(5, 3)
sum(5)
sum(b = 5)
sum()

Теперь параметр a является обязательным, поэтому два вызова функции sum поднимут ошибку TypeError (про исключения мы говорили в уроке 10.5). Постарайтесь определить какие без запуска кода.

Как видите, все достаточно просто. Вернемся к обещанным основам передачи аргументов в Python. Вспомним урок 2.3., где мы разбирались с типами данных и как работает присвоение в Python. Рассмотрим пример:

Пример
def sum(a, b):
    print(a + b)
    print(id(a), id(b))

c = 5
d = 3

print(id(c), id(d))

sum(c, d)

Из этого примера становится ясно о способе передачи аргументов в функцию – через указатели. Аргументы никогда автоматически не копируются, например, как в Си, передача по умолчанию осуществляется по значению (by value). Рассмотрим следующий пример:

Пример
def sum(a, b):
    print(a + b)
    a = 10
    b = 10

a = 5
b = 3

sum(a, b)

print(a, b) # => 5 3

Об этом говорили в уроке 13.3. Не про параметры функции, а про область видимости, но сути не меняет. Присваивание параметрам внутри функции не влияет на вызывающий код. То есть то что вы изменили переменные a и b, повлияет на значения a и b в теле функции sum и никак не коснется a и b в теле основной программы. Но и здесь есть свои нюансы. А именно, мы присваивали самим именам аргументов.

Что если передать изменяемый объект в функцию, например, список? Далее пример:

Пример
def pr(a, b):
    print(a, b)
    a = 10
    b[1] = 1

a = 5
b = [1, 2, 3]

pr(a, b)

print(a, b) # => 5 [1, 1, 3]

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

Оператор return

Чтобы вернуть значение из функции, можно использовать оператор return. Далее просто пример:

Пример
def sum(a, b):
    c = a + b
    return c

print(sum(2, 3)) # => 5

И это не все чудеса Python. При помощи оператора return можно возвращать несколько значений, если их указать через запятую. Оператор return упакует их в кортеж и вернет:

Пример
def sum(a, b):
    c = a + b
    return c, a, b

print(sum(2, 3)) # => (5, 2, 3)

Помните про распаковку кортежей? В уроке 9.2. мы немного об этом говорили. Рассмотрим пример:

Пример
def sum(a, b):
    c = a + b
    return c, a, b

c, a, b = sum(2, 3)
print(c) # => 5
print(a) # => 2
print(b) # => 3

Звездочки (*) в Python

Я вас обманул, что в уроке 9.2. мы говорили про распаковку кортежей. Сейчас это буду исправлять. Будем говорить о префиксных операторах * и **, а не инфиксных (форма записи, когда оператор записан между операндами), т.е. речь пойдет не о умножении и возведении в степень:

Пример
a * b
a ** b

Использовать * и ** можно для передачи аргументов в функцию, сбора переданных в функцию аргументов. Оператор * можно использовать для распаковки кортежей (о чем было в уроке 9.2.) и распаковки итерируемых объектов в список/кортеж. Оператор ** можно использовать для принятия только именованных аргументов или распаковки словарей в другие словари.

Рассмотрим пример распаковки итерируемого объекта в аргументы функции.

Пример
def sum(a, b):
    print(a + b)

a = (3, 4)
sum(*a)

Далее пример распаковки словаря. Обратите внимание на ключи словаря и вывод программы:

Пример
def sum(a, b):
    print(a) # => 5
    print(b) # => 4
    print(a + b) # => 9

a = {"b": 4, "a": 5}
sum(**a)

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

Пример
def sum(*a):
    b, c = a
    print(b + c) # => 8

sum(2, 6)

При помощи оператора ** можно собрать аргументы в словарь:

Пример
def sum(**a):
    print(a) # => {'one': 1, 'two': 2}

sum(one=1, two=2)

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

Пример
def sum(*a, b):
    print(a, b) # => (1, 2, 3) 4

sum(1, 2, 3, b=4)

Еще один пример про распаковку итерируемого объекта при помощи оператора *:

Пример
s = (1, 2, 3, 4, 5, 6, 7, 8, 9)
a, b, *c = s
print(a) # => 1
print(b) # => 2
print(c) # => [3, 4, 5, 6, 7, 8, 9]

Последний на сегодня пример со звездочками:

Пример
a = {"a": 1, "b": 2, "c": 3}
b = {"c": 4, "d": 5}
c = {**a, **b}
d = {**b, **a}

print(c) # => {'a': 1, 'b': 2, 'c': 4, 'd': 5}
print(d) # => {'c': 3, 'd': 5, 'a': 1, 'b': 2}

В этом примере мы объединили два словаря в один. Обратите внимание на ключ c, в первом и втором словаре. Значение в этом ключе перезаписывается значением из второго словаря.

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

ПРОЧИТАНО
Следующий урок
<
×
>
Впервые на сайте Codebra?

Извините за это всплывающее окно, меня они тоже раздражают.

Образовательный ресурс codebra.ru полностью посвящен программированию. Все курсы и уроки находятся на главной странице. Ради интереса можете посмотреть на содержимое курсов по Python, HTML и CSS, JavaScript, C++ и другие, размещенные на главной странице.

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

Удачи в обучении!

Закрыть окно