Зарегистрируйтесь, чтобы продолжить обучение

Операторы распаковки Python: Функции

* и **-операторы в вызовах функций синтаксически идентичны им в определениях, но выполняют обратное действие. Посмотрим на примере функции sum():

def sum(*numbers):
    result = 0
    for num in numbers:
        result += num
    return result

Вызовем sum(), применив *-оператор к списку аргументов:

numbers = [1, 7, 4]
sum(*numbers)  # 12

Здесь, знакомый нам *-оператор, уже распаковывает список на аргументы. Количество полученных аргументов равно количеству элементов массива. По сути, код выше преобразуется в вызов:

sum(numbers[0], numbers[1], numbers[2])
# sum(1, 7, 4)

Как и в случае с определением функций, *-оператор может использоваться совместно с позиционными аргументами:

numbers = [1, 7, 4]
sum(8, *numbers)  # 20

sum(8, 10, *numbers)  # 30
sum(8, 10, 70, *numbers)  # 100

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

numbers = [1, 7, 4]

sum(8, 10, *numbers)  # 30
sum(8, *numbers, 10)  # 30
sum(*numbers, 8, 10)  # 30

Более того, может быть любое количество операторов распаковки и в любом порядке:

numbers1 = [1, 7, 4]
numbers2 = [5, 5]

# sum(1, 7, 4, 5, 5)
sum(*numbers1, *numbers2)  # 22

# sum(5, 5, 1, 7, 4)
sum(*numbers2, *numbers1)  # 22

# sum(8, 1, 7, 4, 10, 5, 5)
sum(8, *numbers1, 10, *numbers2)  # 40

Распаковка именованных аргументов

По аналогии с оператором распаковки позиционных аргументов работает и оператор распаковки именованных - **-оператор.

def func(**kwargs):
    for key, value in kwargs.items():
        print("key = ", key)
        print("value = ", value)


d = {"a": 42, "b": "python"}

# распаковываем словарь
func(**d)
# key =  a
# value =  42
# key =  b
# value =  python

Важно, что в примере выше, если мы забудем распаковать словарь, то получим ошибку. Ведь функция принимает не словарь, а любое количество именованных аргументов. Уже в вызове функции (func(**d)) **-оператор распаковывает переданный словарь в именованные аргументы вида a=42, b='python'. Затем оператор упаковки в определении функции (func(**kwargs)), собирает их в словарь kwargs, который мы и обрабатываем в функции.

def func(**kwargs):
    for key, value in kwargs.items():
        print("key = ", key)
        print("value = ", value)


d = {"a": 42, "b": "python"}
func(d)  # TypeError: func() takes 0 positional arguments but 1 was given

Оператор ** упаковки-распаковки удобно использовать в функциях, принимающих неограниченное количество опций, например, функциях конфигурации:

def get_config(**options):
    default_options = {"case": "lower", "output": "console"}
    # возвращаем новые опции
    return default_options | options


get_config()  # {'case': 'lower', 'output': 'console'}
get_config(**{"case": "upper"})  # {'case': 'upper', 'output': 'console'}

get_config(**{"case": "upper", "code": "utf-8"})
# {'case': 'upper', 'output': 'console', 'code': 'utf-8'}

Итог

Оба оператора упаковки и распаковки обозначаются символами * и **. Чтобы их не путать при работе с функциями, нужно следовать следующим принципам:

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

Сочетая эти операторы мы можем создавать функции работающие с любым числом аргументов.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff