Что обозначают args и kwargs при определении функции в python
Одной из распространенных сфер, где применяются упаковка и распаковка — это параметры функций. Так, в определениях различных функций нередко можно увидеть, что они принимают такие параметры как *args и **kwargs .
Термины args и kwargs — это соглашения по программированию на Python, в реальности вместо них можно использовать любые именования. *args представляет параметры, которые передаются по позиции. А **kwargs означает параметры, которые передаются по имени. обозначает аргументы ключевого слова.
Оператор * применяется с любым итерируемым объектом (например, кортежем, списком и строками). Тогда как оператор ** можно использовать только со словарями.
*args
Оператор * позволяет передать в функцию несколько значений, и все они будут упакованы в кортеж:
def fun(*args): # обращаемся к первому элементу кортежа print(args[0]) # выводим весь кортеж print(args) fun("Python", "C++", "Java", "C#")
Здесь функция fun принимает кортеж значений. При вызове мы можем передать ей различное количество значений. Так, в примере выше передается четыре строки, которые образуют кортеж. Консольный вывод программы:
Python ('Python', 'C++', 'Java', 'C#')
Благодаря такой возможности мы можем передавать в функцию переменное количество значений:
def sum(*args): result = 0 for arg in args: result += arg return result print(sum(1, 2, 3)) # 6 print(sum(1, 2, 3, 4)) # 10 print(sum(1, 2, 3, 4, 5)) # 15
Оператор **
Оператор ** упаковывает аргументы, переданные по имени, в словарь. Имена параметров служат ключами. Например, определим функцию, которая просто будет выводить все переданные параметры
def fun(**kwargs): print(kwargs) # выводим словарь на консоль fun(name="Tom", age="38", company="Google") fun(language="Python", version="3.11")
Консольный вывод программы:
Поскольку аргументы передаются в функцию в виде словаря, то внутри функции через ключи мы можем получить их значения:
def fun(**kwargs): for key in kwargs: print(f" = ") fun(name="Tom", age="38", company="Google")
Консольный вывод программы:
name = Tom age = 38 company = Google
Распаковка аргументов
Выше было описано, как операторы * и ** применяются для упаковки аругментов в кортеж и словарь соответственно. Но эти же операторы могут использоваться для распаковки.
Оператор * и распаковка
Сначала рассмотрим ситуацию, где это может пригодиться.Пусть мы передаем в функцию кортеж:
def sum(*args): result = 0 for arg in args: result += arg return result numbers = (1, 2, 3, 4, 5) print(sum(numbers))
Здесь в вызов функции sum передается кортеж. Параметр *args по сути тоже представляет кортеж, и кажется, все должно работать. Тем не менее мы столкнемся с ошибкой
TypeError: unsupported operand type(s) for +=: 'int' and 'tuple'
То есть в данном случае кортеж numbers передается как элемент кортежа *args .
И чтобы элементы кортежа были переданы в кортеж *args как отдельные значения, необходимо выполнить их распаковку:
def sum(*args): result = 0 for arg in args: result += arg return result numbers = (1, 2, 3, 4, 5) # применяем распаковку - *numbers print(sum(*numbers)) # 15
Здесь при передачи кортежа numbers в функцию sym применяется распаковка: *numbers
Другим случаем распаковки может быть ситуация, когда функция принимает несколько параметров, а мы передаем один кортеж или список:
def print_person(name, age, company): print(f"Name:, Age: , Company: ") person =("Tom", 38, "Google") # выполняем распаковку кортежа person print_person(*person) # Name:Tom, Age: 38, Company: Google
В данном случае выражение *person раскладывает кортеж person на отдельные значения, которые передаются параметрам name, age и company.
Оператор ** и распаковка
Оператор ** применяется для распаковки словарей:
def print_person(name, age, company): print(f"Name:, Age: , Company: ") tom = # выполняем распаковку словаря tom print_person(**tom) # Name:Tom, Age: 38, Company: Google
Здесь выражение **tom раскладывает словарь на отдельные значения, которые передаются параметрам name, age и company по названию ключей.
Сочетание параметров
Параметры *args и *kwargs могут использоваться в функции вместе с другими параметрами. Например:
def sum(num1, num2, *nums): result=num1+num2 for n in nums: result += n return result print(sum(1,2,3)) # 6 print(sum(1,2,3,4)) # 10
Переменные аргументов *args и **kwargs в функции Python
Передача произвольного числа аргументов в функцию Python
Наконец, наименее часто используемая опция, это когда функция вызываться с произвольным числом аргументов. Обычно они указываются последними в списке формальных параметров, потому что собирают все оставшиеся входные аргументы, которые передаются в функцию.
При определении функции, параметры с произвольным числом аргументов указывают как:
- *args — произвольное число позиционных аргументов. При вызове функции, на место этого параметра передается список аргументов, заключенных в кортеж. Перед *args может быть ноль или более нормальных аргументов. Любые формальные параметры, которые появляются после параметра *args , являются аргументами «только для ключевых слов». Это означает, что следующие за *args параметры могут использоваться только как ключевые аргументы, а не как позиционные.
- **kwargs — произвольное число именованных аргументов. При вызове функции, на его место передается список именованных аргументов заключенных в словарь, кроме тех, имена которых были определены ранее. Параметр **kwargs может быть определен совместно с другим формальным параметром *args . Параметр **kwargs указывается последним в области определения формальных параметров функции.
Примечание: один символ * в имени параметра функции args распаковывает список или кортеж для передачи позиционных аргументов, а два символа ** в имени параметра функции **kwargs распаковывает словарь для передачи ключевых аргументов в функцию при ее вызове.
Имена *args и **kwargs по негласному соглашению принято использовать в документации Python. На самом деле никто не запрещает брать любые другие имена переменных. Например, для словарей наряду c **kwargs иногда используют **options .
Пример использования *args :
def chees(*arguments): for arg in arguments: print(arg) word = ("It's very runny, sir.", "It's really very.", "VERY runny, sir.") chees(*word) # Выведет It's very runny, sir. It's really very. VERY runny, sir.
Пример использования **kwargs :
def shop(**keywords): for kw in keywords: print(kw, ":", keywords[kw]) kword = shopkeeper:"Michael Palin", client:"John Cleese", sketch:"Cheese Shop Sketch"> shop(**kword) # Выведет shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch
Распаковку можно использовать несколько раз. На примере словаря:
def process_data(a, b, c, d): print(a, b, c, d) x = 'a': 1, 'b': 2> y = 'c': 3, 'd': 4> process_data(**x, **y) 1 2 3 4 process_data(**x, c=23, d=42) 1 2 23 42
Пример совместного использования *args и **kwargs :
def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) for kw in keywords: print(kw, ":", keywords[kw])
Функцию cheeseshop можно вызвать так:
word = ("It's very runny, sir.", "It's really very.", "VERY runny, sir.") kword = shopkeeper:"Michael Palin", client:"John Cleese", sketch:"Cheese Shop Sketch"> cheeseshop("Limburger", *word, **kword)
и, конечно, функция выведет:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very. VERY runny, sir. ---------------------------------------- shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функции это объекты
- Функции могут иметь атрибуты
- Функции могут храниться в структурах данных
- Функции могут быть вложенными
- Передача функции в качестве аргумента другой функции
- Область видимости переменных функции
- Операторы global и nonlocal
- Параметры (аргументы) функции
- Ключевые аргументы в определении функции Python
- Значение аргумента по умолчанию в функциях Python
- Варианты передачи аргументов в функцию Python
- Переменные аргументов *args и **kwargs в функции Python
- Распаковка аргументов для передачи в функцию Python
- Как оцениваются аргументы при вызове функции?
- Строгие правила передачи аргументов в функцию Python
- Инструкция return
- Анонимные функции (lambda-выражения)
- Строки документации в функциях Python
- Рекурсия
- Замыкания в функциях Python
- Перегрузка функций
Функция с переменным количеством аргументов в Python: *args и **kwargs
Не всегда заранее известно, сколько аргументов будет передано функции. В таких случаях в Python на помощь приходят *args и **kwargs, позволяющие передавать переменное количество аргументов. Сегодня мы расскажем, как именно они работают.
В этой статье мы расскажем, зачем нужны *args и **kwargs в Python и как их использовать.
В программировании, если нам нужно выполнять похожие действия, мы определяем функции для многоразового использования кода. Чтобы выполнить это действие, мы вызываем функцию с определённым значением — аргументом.
Предположим, у нас есть функция, которая складывает три числа:
def adder(x, y, z): print("sum:",x + y + z) adder(10, 12, 13)
После запуска будет выведено sum: 35 .
Во фрагменте кода выше у нас есть функция adder() с тремя аргументами: x , y и z . При передаче трёх значений этой функции на выходе мы получаем их сумму. Но что, если передать больше трёх аргументов в эту функцию?
def adder(x, y, z): print("sum: ",x + y + z) adder(5, 10, 15, 20, 25)
Из-за того, что здесь мы передаём 5 аргументов, при запуске программы выводится ошибка TypeError: adder() takes 3 positional arguments but 5 were given .
*args и **kwargs спешат на помощь
В Python можно передать переменное количество аргументов двумя способами:
- *args для неименованных аргументов;
- **kwargs для именованных аргументов.
Мы используем *args и **kwargs в качестве аргумента, когда заранее не известно, сколько значений мы хотим передать функции.
*args
Как было сказано, *args нужен, когда мы хотим передать неизвестное количество неименованных аргументов. Если поставить * перед именем, это имя будет принимать не один аргумент, а несколько. Аргументы передаются как кортеж и доступны внутри функции под тем же именем, что и имя параметра, только без * . Например:
def adder(*nums): sum = 0 for n in nums: sum += n print("Sum: ", sum) adder(3, 5) adder(4, 5, 6, 7) adder(1, 2, 3, 5, 6)
В результате выполнения программы мы получим следующий результат:
Sum: 8 Sum: 22 Sum: 17
Здесь мы использовали *nums в качестве параметра, который позволяет передавать переменное количество аргументов в функцию adder() . Внутри функции мы проходимся в цикле по этим аргументам, чтобы найти их сумму, и выводим результат.
**kwargs
По аналогии с *args мы используем **kwargs для передачи переменного количества именованных аргументов. Схоже с *args , если поставить ** перед именем, это имя будет принимать любое количество именованных аргументов. Кортеж/словарь из нескольких переданных аргументов будет доступен под этим именем. Например:
def intro(**data): print("\nData type of argument: ",type(data)) for key, value in data.items(): print("<> is <>".format(key, value)) intro(Firstname="Sita", Lastname="Sharma", Age=22, Phone=1234567890) intro(Firstname="John", Lastname="Wood", Email="johnwood@nomail.com", Country="Wakanda", Age=25, Phone=9876543210)
При запуске программы мы увидим следующее:
Data type of argument: Firstname is Sita Lastname is Sharma Age is 22 Phone is 1234567890 Data type of argument: Firstname is John Lastname is Wood Email is johnwood@nomail.com Country is Wakanda Age is 25 Phone is 9876543210
В этом случае у нас есть функция intro() с параметром **data . В функцию мы передали два словаря разной длины. Затем внутри функции мы прошлись в цикле по словарям, чтобы вывести их содержимое.
Что нужно запомнить:
- *args и **kwargs — специальный синтаксис, позволяющий передавать в функцию переменное количество аргументов. При этом, совсем не обязательно использовать имена аргументов args и kwargs;*args используется для неименованных аргументов, с которыми можно работать как со списком;**kwargs используется для именованных аргументов, с которыми можно работать как со словарём;если вы хотите использовать и *args, и **kwargs, то это делается так: func(fargs, *args, **kwargs), порядок следования аргументов важен;
Другие материалы по Python можно посмотреть у нас на сайте.
Django Fan

Если функции передается список, то его элементы должны следовать в строго обусловленном заранее порядке, или, другими словами, на своих позициях (иначе как мы узнаем, что собой представляет определенный элемент списка?). Например, если функция sign_up() ждет от нас список [name, age, gender] , то мы должны строго соблюдать этот порядок; мы не можем вызвать функцию sign_up(age, name, gender) . Такие аргументы называются неименованными или позиционными.
Если же в качестве аргумента функции передается словарь, то порядок следования может быть произвольный, т.к. элементы словаря передаются с ключами, их уже не перепутаешь. Такие аргументы называются именованными.
Продолжая пример в примечании, обозначим наш список через переменную:
user_data_list = [name, age, gender]
А переменную передадим в функцию:
sign_up(*user_data_list)
При этом, чтобы функция восприняла в качестве аргумента не один объект (а коллекции также являются объектами как и вообще всё в Python), а несколько, коллекцию нужно распаковать. Как раз это и делают звездочки. Записи такого типа (с одной или двумя звездочками) в Python используются в двух случаях: при вызове (как мы сделали только что) и при определении функции.
*args и **kwargs при определении функции
Аргументы функции в 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
Функция с именованными аргументами задается так:
>>> 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, будет лучше выбрать более информативные имена (хотя в следующем примере мы не далеко в этом продвинулись =) ):
>>> def print_names(name1, name2, name3): . print("имя 1:", name1) . print("имя 2:", name2) . print("имя 3:", name3) . >>> name_list = ("Маша", "Витя") >>> print_names("Коля", *name_list) имя 1: Коля имя 2: Маша имя 3: Витя
Аргументы можно передавать и так:
>>> print_names(*['Коля', 'Маша', 'Витя']) имя 1: Коля имя 2: Маша имя 3: Витя
Следующий пример показывает вызов функции с именованными аргументами:
>>> name_dic = >>> print_names("Коля", **name_dic) имя 1: Коля имя 2: Маша имя 3: Витя
То же самое с литералом:
>>> print_names(**) имя 1: Коля имя 2: Маша имя 3: Витя
Заключение
Итак, если кратко подытожить вышесказанное, то звездочки в Python используют в следующих случаях:
- При определении функции, если функция принимает неопределенное количество аргументов.
- При вызове функции, когда ей нужно передать несколько объектов в виде коллекции. Обратите внимание, не объект коллекции, а объекты, содержащиеся в коллекции. Таким образом, обозначения *args и **kwargs распаковывают коллекцию и передают ее элементы в функцию.
