Урок 21 из 84 · Основы Python

*args, **kwargs

Содержание урока

Чтобы получить ответ на вопрос в заголовке, разделим его на две части:

  1. Что такое args и kwargs?
  2. Что обозначают звездочки?

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

Примечание:

Если функции передается список, то его элементы должны следовать в строго обусловленном заранее порядке, или, другими словами, на своих позициях (иначе как мы узнаем, что собой представляет определенный элемент списка?). Например, если функция sign_up() ждет от нас список [name, age, gender], то мы должны строго соблюдать этот порядок; мы не можем вызвать функцию sign_up(age, name, gender). Такие аргументы называются неименованными или позиционными.

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

именованными.

Продолжая пример в примечании, обозначим наш список через переменную:

Python

user_data_list = [name, age, gender]

А переменную передадим в функцию:

Python

sign_up(*user_data_list)

При этом, чтобы функция восприняла в качестве аргумента не один объект (а коллекции также являются объектами как и вообще всё в Python), а несколько, коллекцию нужно

распаковать

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

args и *kwargs при определении функции

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

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

. Очень мудрено. На самом деле это

коллекции

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

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

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

Python

>>> def test_var_args(farg, *args):
...     print("formal arg:", farg)
...     for arg in args:
...         print("another arg:", arg)
...
>>> test_var_args(1, "two", 3)
formal arg: 1
another arg: two
another arg: 3

Функция с именованными аргументами задается так:

Python

>>> def test_var_kwargs(farg, **kwargs):
...     print("formal arg:", farg)
...     for key in kwargs:
...         print("another keyword arg: %s: %s" % (key, kwargs[key]))
...
>>> test_var_kwargs(farg=1, myarg2="two", myarg3=3)
formal arg: 1
another keyword arg: myarg2: two
another keyword arg: myarg3: 3

Так что же такое args и kwargs?!!

Теперь вы готовы усвоить всю правду об этом :)

Имена args и kwargs по негласному соглашению принято использовать в документации Python. На самом деле никто не запрещает брать любые другие валидные имена переменных. Например, для словарей наряду c **kwargs иногда используют **options.

Применение  и * при вызове функции

Теперь посмотрим как

вызывать

функцию с позиционными аргументами (уже демонстрировали выше). Здесь уже меньше смысла в args и kwargs, будет лучше выбрать более информативные имена (хотя в следующем примере мы не далеко в этом продвинулись =) ):

Python

>>> def print_names(name1, name2, name3):
...     print("имя 1:", name1)
...     print("имя 2:", name2)
...     print("имя 3:", name3)
...
>>> name_list = ("Маша", "Витя")
>>> print_names("Коля", *name_list)
имя 1: Коля
имя 2: Маша
имя 3: Витя

Аргументы можно передавать и так:

Python

>>> print_names(*['Коля', 'Маша', 'Витя'])
имя 1: Коля
имя 2: Маша
имя 3: Витя

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

Python

>>> name_dic = {"name3": "Витя", "name2": "Маша"}
>>> print_names("Коля", **name_dic)
имя 1: Коля
имя 2: Маша
имя 3: Витя

То же самое с литералом:

Python

>>> print_names(**{'name1': 'Коля', 'name2': 'Маша', 'name3': 'Витя'})
имя 1: Коля
имя 2: Маша
имя 3: Витя

Заключение

Итак, если кратко подытожить вышесказанное, то звездочки в Python используют в следующих случаях:

  1. При определении функции, если функция принимает неопределенное количество аргументов.
  2. При вызове функции, когда ей нужно передать несколько объектов в виде коллекции. Обратите внимание, не объект коллекции, а объекты, содержащиеся в коллекции. Таким образом, обозначения args и *kwargs распаковывают коллекцию и передают ее элементы в функцию.
Отзыв