Упаковка и распаковка в параметрах функций

Последнее обновление: 01.02.2023

Одной из распространенных сфер, где применяются упаковка и распаковка - это параметры функций. Так, в определениях различных функций нередко можно увидеть, что они принимают такие параметры как *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")

Консольный вывод программы:

{'name': 'Tom', 'age': '38', 'company': 'Google'}
{'language': 'Python', 'version': '3.11'}

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

def fun(**kwargs):
    for key in kwargs:
        print(f"{key} = {kwargs[key]}")
 
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:{name}, Age: {age}, Company: {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:{name}, Age: {age}, Company: {company}")
 
tom ={"name":"Tom", "age":38, "company":"Google"}
# выполняем распаковку словаря 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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850