- Что такое args и kwargs в Python
- Зачем нам нужны * args и ** kwargs?
- Пример с * args
- Что это за тип * args и ** kwargs?
- Пример с ** kwargs
- Передача кортежа и словаря для сопоставления
- Когда использовать?
- Имитация ответа функции
- Функция декоратора
- Функция с переменным количеством аргументов в Python: *args и **kwargs
- *args и **kwargs спешат на помощь
- *args
- **kwargs
Что такое args и kwargs в Python
Python позволяет нам определять три типа аргументов для функции:
- Формальные аргументы, например def add (a, b).
- Переменное количество аргументов без ключевых слов с использованием * args, например def add (* args).
- Переменное количество аргументов с ключевыми словами или именованных аргументов с использованием ** kwargs, например def add (** kwargs).
Некоторые важные моменты об аргументах функций:
- Когда мы определяем аргументы функции, порядок должен быть формальными аргументами, за которыми следуют * args и ** kwargs.
- Не обязательно использовать имена args и kwargs, мы можем использовать и другие имена. Однако их использование принято по соглашению. Это упростит чтение и понимание вашего кода.
- Переменная args имеет тип tuple. Мы можем передать кортеж в качестве аргумента функции для map с args.
- Переменная kwargs имеет тип dict. Таким образом, мы можем передать словарь в качестве аргумента для сопоставления с kwargs.
Зачем нам нужны * args и ** kwargs?
Допустим, у нас есть функция для сложения двух чисел:
def add_two_numbers(a, b): return a + b
Теперь мы хотим расширить это, чтобы добавить три числа. Мы не можем просто изменить эту функцию, потому что она может использоваться в других местах, и это будет серьезное изменение. Итак, мы вводим еще одну функцию для сложения трех чисел.
def add_three_numbers(a, b, c): return a + b + c
Вы видите, к чему я клоню, верно? Поскольку у нас есть возможность указать переменное количество аргументов для функции, мы можем определить универсальную функцию для сложения чисел.
Пример с * args
Давайте определим универсальную функцию для сложения чисел с использованием переменных * args.
def add(*args): total = 0 for arg in args: total = total + arg return total print(add(1, 2)) print(add(1, 2, 3)) print(add(1, 2, 3, 4))
Что это за тип * args и ** kwargs?
def zap(*args, **kwargs): print(type(args)) print(type(kwargs)) zap()
Пример с ** kwargs
Давайте определим функцию, чтобы показать использование переменных ** kwargs.
def kwargs_processor(**kwargs): for k, v in kwargs.items(): print(f'Key= and Value=') kwargs_processor(name='Pankaj', age=34) kwargs_processor(country='India', capital='New Delhi')
Key=name and Value=Pankaj Key=age and Value=34 Key=country and Value=India Key=capital and Value=New Delhi
Передача кортежа и словаря для сопоставления
Давайте посмотрим, как передать значения кортежа для сопоставления с элементами args и словаря переменной kwargs.
t = (10, 30, 60) print(add(*t)) d = kwargs_processor(**d)
100 Key=name and Value=Pankaj Key=age and Value=34
Обратите внимание на использование * при использовании кортежа для сопоставления его значений с аргументами. Аналогичным образом ** используется для сопоставления элементов dict с переменной kwargs.
Когда использовать?
Вы можете использовать их в любой функции, где вы ожидаете переменное количество аргументов. Однако они очень полезны в двух конкретных случаях — имитация ответа функции и написание общей функции-декоратора.
Имитация ответа функции
Допустим, у нас есть класс API, определенный следующим образом:
class APIHelper: def call_api(self, url, input_json): # some complex logic return 'complex_response_data'
Мы можем создать функцию симулятора тестирования и сопоставить ее с функцией API, чтобы сгенерировать тестовый ответ.
class MyTestClass: def test_call_api(self, *args, **kwargs): return "test_response_data" # Assign API function to use our test function APIHelper.call_api = MyTestClass.test_call_api
Давайте теперь посмотрим, что произойдет, когда мы будем использовать наши функции API.
ah = APIHelper() print(ah.call_api()) print(ah.call_api(1, url='https://www.journaldev.com', input_json=<>)) print(ah.call_api(1, 2, url='https://www.journaldev.com'))
test_response_data test_response_data test_response_data
Функция декоратора
Давайте посмотрим, как мы можем определить функцию-декоратор для регистрации переменных функции.
def log_arguments(func): def inner(*args, **kwargs): print(f'Arguments for args:, kwargs:') return func(*args, **kwargs) return inner
Теперь мы можем использовать эту функцию декоратора с любой другой функцией для записи их аргументов в консоль.
@log_arguments def foo(x, y, z): return x + y + z sum_ints = foo(1, 2, z=5) print(sum_ints) @log_arguments def bar(x, *args, **kwargs): total = x for arg in args: total = total + arg for key, value in kwargs.items(): total = total + value return total sum_ints = bar(1, 2, 3, a=4, b=5) print(sum_ints)
Arguments for args:(1, 2), kwargs: 8 Arguments for args:(1, 2, 3), kwargs: 15
Функция с переменным количеством аргументов в 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
Как было сказано, *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)
В результате выполнения программы мы получим следующий результат:
Здесь мы использовали *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 можно посмотреть у нас на сайте.