Если вы какое-то время программировали на Python, то, скорее всего, вы сталкивались с таким синтаксисом: (*args и **kwargs).

Эти два синтаксиса (args и **kwargs) используются как в объявлении функции, так и в вызове функции. Важно отметить, что слова «args» и «kwargs» после одиночной звездочки (*) и двойной звездочки (**) соответственно не обязательны и могут быть заменены любым именем переменной, но «args» и «kwargs» обычно используются в сообществе Python. «args» — это сокращение от «аргументы», а «kwargs» — «аргументы ключевого слова».

Аргументы — это данные/значения, передаваемые вызову функции.
Параметры — это переменные, указанные при объявлении функции, они служат зависимостями для функции.

[*]:: Одиночная звездочка (*)
1. Всякий раз, когда вы определяете функцию и указываете *args в качестве параметра, вы просто говорите, что можно передать как можно больше позиционных аргументов. во время вызова функции. Вы не ограничиваете вызывающую функцию каким-либо конкретным количеством позиционных аргументов. Это все равно, что сказать: «Передайте мне любое количество позиционных аргументов, я знаю, как с ними обращаться».

Позиционные аргументы: когда аргументы передаются вызову функции в определенном порядке, они будут захвачены функцией с использованием этого порядка. То есть 1-й аргумент сопоставляется с первым параметром, 2-й аргумент сопоставляется со вторым параметром и так далее.

Давайте посмотрим на это.

def count_numbers(*args):
   print(args)

В определении функции count_numbers мы используем *args в качестве параметра. Это просто означает, что при вызове функции count_numbers ей может быть передано любое количество аргументов (позиционных). Итак, давайте попробуем.
[*]Использование

count_numbers(1,2,3,4,5)

[*]Вывод
(1, 2, 3, 4, 5)
[*]Использование

count_numbers(1,2)

[*]Вывод
(1, 2)

Становится очевидным, что позиционные аргументы, переданные во время вызова функции (т. е. counter_numbers (1,2)) фиксируются в функции как Tuple (тип данных). Таким образом, мы можем получить к ним доступ на основе их позиции (индекс начинается с нуля)
[*]Snippet

def count_numberss(*args):
   a = args[0]
   b = args[1]
   print("a:",a)
   print("b",b)

[*]Использование

count_numbers(1,2)

[*]Вывод
а: 1
б 2

2. Второе использование * в вызове функции. Всякий раз, когда вы вызываете/вызываете функцию и передаете аргументы как (*var). То, что вы делаете, это распаковка аргумента функции. Помещение * перед итерируемым объектом распаковывает (то есть разделяет) его и передает его элементы в качестве отдельного позиционного аргумента вызову функции. Простой пример объясняет лучше.

[*]Фрагмент

def printer(a,b,c):
   print("A:", a)
   print("B:", b)
   print("C:", c)

my_list_items = ["A", "B", "C"]
printer(*my_list_items)

Мы объявили переменную с именем my_list_items, затем при вызове функции «printer» мы передали аргумент «my_list_items» с префиксом *. Как мы уже упоминали, итерируемый объект (например, my_list_items в данном случае) будет распакован, и его элемент будет передан как отдельный позиционный аргумент.
Вот что происходит после распаковки итерируемого объекта и передачи элементов по отдельности
printer("A", "B", "C")

[*]Вывод
A: A
B: B
C: C

Обратите внимание, что элемент, который будет распакован, должен быть итерируемым (например, строки, кортеж, список и т. д.).

[*]:: Двойные звездочки (**)
1. Точно так же, как одиночная звездочка (*) работает с позиционными аргументами, ** работает с аргументами ключевого слова .
Аргументы с ключевыми словами идентифицируются по их именам, а не по их позициям.
— Всякий раз, когда вы определяете функцию и указываете **kwargs в качестве параметра, это означает, что вызывающая функция может передавать различные аргументы ключевого слова, не ограничивая их. Самое классное в этом то, что это дает вам возможность выбирать из аргументов все, что вам нужно. Скажем, у вас есть функция, в которой вам нужно только имя пользователя. Идея состоит в том, что ваш код всегда будет работать, даже если вызывающая функция передаст некоторые дополнительные аргументы (например, возраст), которые вам не нужны.

Напомним, что аргументы, передаваемые с помощью * (одна звездочка), захватываются как Tuple, как объяснялось выше. Аргументы, переданные с помощью **(двойные звездочки), фиксируются как словарь Python
Давайте посмотрим на эту функцию
[*]Snippet

def greet(**kwargs):
   print("Good day,", kwargs['name'])
   print("All keyword args",kwargs)

greet(name="Ray", email="[email protected]", is_active=True)

[*]Вывод
Добрый день, Рэй
Все аргументы ключевых слов {‘name’: ‘Ray’, ‘email’: ‘[email protected]’’, ‘is_active’: True}

Большой! **kwargs позволяет передавать как можно больше аргументов ключевых слов.

2. Когда вы вызываете функцию и передаете аргументы как **var, это означает, что словарь 'var' должен быть передан в вызов функции в качестве аргумента keywords.
[*]Фрагмент

var = {"name":"Kay","user_id":9}
greet(**var)

По сути, вы говорите здесь, что словарь 'var' (тип данных) должен быть передан в функцию приветствия () в качестве аргумента ключевых слов.
Таким образом, то, что вы написали, эквивалентно:
приветствовать(name=”Кей”, user_id=9)

Время проверить
[*]Snippet

def greet(**kwargs):
   print("Good day,", kwargs['name'])
   print("All keyword args",kwargs)
  
var = {"name":"Kay","user_id":9}
greet(**var)

[*]Вывод
Добрый день, Кей
Все аргументы ключевого слова {‘имя’: ‘Кей’, ‘user_id’: 9}

Оно работает!!!!

Подведение итогов:

  • В определении функции *args означает, что при вызове функции может быть передано любое количество позиционных аргументов. Он будет захвачен как кортеж
  • В вызове функции *args означает распаковку итерируемых объектов. каждый элемент итераций будет передан как отдельные позиционные аргументы в вызове функции
  • В определении функции **kwargs означает, что при вызове функции может быть передано любое количество аргументов ключевого слова. Это будет захвачено как словарь
  • В вызове функции **kwargs означает, что словарь должен быть передан в вызов функции в качестве аргументов ключевого слова.

Я надеюсь, вам понравится это. Спасибо за прочтение