*args и **kwargs
Обычно при вызове функции нужно передать правильное количество аргументов.
Но иногда нельзя заранее сказать, сколько их будет передано.
Именно эту задачу решают *args и **kwargs: они позволяют функции принимать неизвестное количество аргументов.
Произвольные аргументы — *args
Когда вы не можете предсказать, сколько аргументов получит функция, поставьте * перед именем параметра.
Тогда функция получит аргументы в виде кортежа и сможет обращаться к каждому элементу по его позиции.
В документации Python произвольные аргументы (Arbitrary Arguments) часто сокращают до *args.
Пример
Приём любого количества аргументов с помощью *args:
*kids принимает любое количество аргументов.
Выведите третьего ребёнка. Вызовите её с "Emil", "Tobias", "Linus".
Вывод: полная программа на Python
def my_function(*kids):
print("Самый младший ребёнок — " + kids[2])
my_function("Emil", "Tobias", "Linus")
Что такое *args?
Функция с параметром *args может принять столько позиционных аргументов, сколько захочет передать вызывающий код.
Все они попадают в args, который внутри функции является кортежем:
Пример
Чтение отдельных аргументов из *args:
*args и выведите тип, первый, второй и все аргументы.
Вызовите её с "Emil", "Tobias", "Linus".
Вывод: полная программа на Python
def my_function(*args):
print("Тип:", type(args))
print("Первый аргумент:", args[0])
print("Второй аргумент:", args[1])
print("Все аргументы:", args)
my_function("Emil", "Tobias", "Linus")
Использование *args вместе с обычными аргументами
Обычные параметры и *args могут стоять рядом.
Обычные параметры нужно указывать первыми.
Здесь greeting принимает значение "Hello", а names собирает все остальные значения.
Пример
greeting и *names.
Выведите приветствие с каждым именем. Вызовите с "Hello", "Emil", "Tobias", "Linus".
Вывод: полная программа на Python
def my_function(greeting, *names):
for name in names:
print(greeting, name)
my_function("Hello", "Emil", "Tobias", "Linus")
Практический пример с *args
Именно в гибких функциях *args действительно помогает:
Пример
Сложение любого количества переданных значений:
*numbers, которая вычисляет сумму любого количества значений.
Проверьте на (1,2,3), (10,20,30,40) и (5).
Вывод: полная программа на Python
def my_function(*numbers):
total = 0
for num in numbers:
total += num
return total
print(my_function(1, 2, 3))
print(my_function(10, 20, 30, 40))
print(my_function(5))
Пример
Поиск наибольшего значения:
*numbers, которая находит максимальное значение.
Для пустого ввода верните None. Проверьте на (3, 7, 2, 9, 1).
Вывод: полная программа на Python
def my_function(*numbers):
if len(numbers) == 0:
return None
max_num = numbers[0]
for num in numbers:
if num > max_num:
max_num = num
return max_num
print(my_function(3, 7, 2, 9, 1))
Произвольные именованные аргументы — **kwargs
Когда вы не можете предсказать, сколько именованных аргументов получит функция, поставьте две звёздочки ** перед именем параметра.
Тогда функция получит их в виде словаря и сможет находить каждый элемент по его ключу.
В документации Python произвольные именованные аргументы (Arbitrary Keyword Arguments) часто сокращают до **kwargs.
Пример
Приём любого количества именованных аргументов с помощью **kwargs:
**kid принимает именованные аргументы.
Выведите фамилию. Вызовите с fname="Tobias", lname="Refsnes".
Вывод: полная программа на Python
def my_function(**kid):
print("Его фамилия — " + kid["lname"])
my_function(fname = "Tobias", lname = "Refsnes")
Что такое **kwargs?
Функция с параметром **kwargs может принять столько именованных аргументов, сколько захочет передать вызывающий код.
Все они попадают в kwargs, который внутри функции является словарём:
Пример
Чтение значений из **kwargs:
**myvar и выведите тип, имя, возраст и все данные.
Вызовите с name="Tobias", age=30, city="Bergen".
Вывод: полная программа на Python
def my_function(**myvar):
print("Тип:", type(myvar))
print("Имя:", myvar["name"])
print("Возраст:", myvar["age"])
print("Все данные:", myvar)
my_function(name = "Tobias", age = 30, city = "Bergen")
Использование **kwargs вместе с обычными аргументами
Обычные параметры и **kwargs тоже работают вместе.
Здесь обычные параметры также указываются первыми:
Пример
username и **details.
Выведите имя пользователя и все дополнительные сведения. Вызовите с "emil123" и дополнительными именованными аргументами.
Вывод: полная программа на Python
def my_function(username, **details):
print("Имя пользователя:", username)
print("Дополнительные сведения:")
for key, value in details.items():
print(" " + key + ":", value)
my_function("emil123", age = 25, city = "Oslo", hobby = "coding")
Сочетание *args и **kwargs
В одной функции могут быть и *args, и **kwargs.
Указывайте параметры в таком порядке:
- обычные параметры
- *args
- **kwargs
Пример
title, *args и **kwargs.
Выведите все три. Вызовите со смешанными позиционными и именованными аргументами.
Вывод: полная программа на Python
def my_function(title, *args, **kwargs):
print("Заголовок:", title)
print("Позиционные аргументы:", args)
print("Именованные аргументы:", kwargs)
my_function("User Info", "Emil", "Tobias", age = 25, city = "Oslo")
Распаковка аргументов
Также можно писать * и ** при вызове функции. Там они распаковывают (разворачивают) список или словарь в отдельные аргументы.
Запомните: в определении * и ** собирают аргументы. При вызове они их распаковывают.
Пример
Превращение списка в отдельные аргументы с помощью *:
*, чтобы распаковать список [1, 2, 3] в вызов функции.
Вывод: полная программа на Python
def my_function(a, b, c):
return a + b + c
numbers = [1, 2, 3]
result = my_function(*numbers) # То же, что: my_function(1, 2, 3)
print(result)
Пример
Превращение словаря в именованные аргументы с помощью **:
fname и lname и выводит приветствие.
Используйте **, чтобы распаковать словарь в вызов функции.
Вывод: полная программа на Python
def my_function(fname, lname):
print("Привет", fname, lname)
person = {"fname": "Emil", "lname": "Refsnes"}
my_function(**person) # То же, что: my_function(fname="Emil", lname="Refsnes")