Python: Функции
Теория: Операторы распаковки
* и **-операторы в вызовах функций синтаксически идентичны им в определениях, но выполняют обратное действие. Посмотрим на примере функции sum():
Вызовем sum(), применив *-оператор к списку аргументов:
Здесь, знакомый нам *-оператор, уже распаковывает список на аргументы. Количество полученных аргументов равно количеству элементов массива. По сути, код выше преобразуется в вызов:
Как и в случае с определением функций, *-оператор может использоваться совместно с позиционными аргументами:
В отличие от оператора упаковки в определении функций, оператор распаковки не обязательно должен быть последним, он может располагаться в любой позиции:
Более того, может быть любое количество операторов распаковки и в любом порядке:
Распаковка именованных аргументов
По аналогии с оператором распаковки позиционных аргументов работает и оператор распаковки именованных - **-оператор.
Важно, что в примере выше, если мы забудем распаковать словарь, то получим ошибку. Ведь функция принимает не словарь, а любое количество именованных аргументов. Уже в вызове функции (func(**d)) **-оператор распаковывает переданный словарь в именованные аргументы вида a=42, b='python'. Затем оператор упаковки в определении функции (func(**kwargs)), собирает их в словарь kwargs, который мы и обрабатываем в функции.
Оператор ** упаковки-распаковки удобно использовать в функциях, принимающих неограниченное количество опций, например, функциях конфигурации:
Итог
Оба оператора упаковки и распаковки обозначаются символами * и **. Чтобы их не путать при работе с функциями, нужно следовать следующим принципам:
- оператор упаковки используется при создании функций. Он позволяет собрать, упаковывать, остаточные аргументы функции
- оператор распаковки используется при вызове функций. Он извлекает элементы из коллекции и заполняет ими параметры функции при вызове
Сочетая эти операторы мы можем создавать функции работающие с любым числом аргументов.



