Переменное количество аргументов функции Python. Как использовать *args и **kwargs в Python 3

Что такое параметры функции в Python? Под этим термином подразумеваются специальные слова, задача которых – передать функции определенные значения. Они используются повсеместно. Ни одно, даже самое простое приложение, не может обойтись без функций и передачи им определенных аргументов. В процессе написания приложения вы, вероятно, не знаете все возможные способы, как будет использоваться код. Поэтому, возможно, вам понадобится в будущем передать разработчикам, работающим с модулем или взаимодействующим с кодом пользователям какие-то возможности. Вот с помощью аргументов *args, **kwargs можно задать динамичное число аргументов для функции. Сегодня поговорим более подробно о том, как правильно работать с ними, и на какие нюансы следует обратить внимание.

Использование *args в Python

Python форму *args используют для того, чтобы отправить список аргументов, которые не играют роль ключевых слов, имеющих переменную длину. Следует учесть то, что звездочка здесь – это важный элемент, поскольку args – это общепринятая идиома. В принципе, она не принуждается к использованию языком, но при этом наличие звездочки позволяет избежать непонимания.

Давайте проанализируем для начала стандартную функцию, которая задействует два аргумента.  

def multiply(x, y):

    print (x * y)

В коде, описанном выше мы создаем функцию, имеющую аргументы x и y. После этого, в процессе вызова функции, необходимо использовать соответствующие числа. В этом случае нами осуществляется передача чисел типа integer – 5 для x и 4 для y. 

def multiply(x, y):

    print (x * y)




multiply(5, 4)

Теперь давайте попробуем посмотреть, что будет, если запустить код с таким содержанием.

python lets_multiply.py

Нами был получен такой результат, демонстрирующий, что целые числа 5 и 4 были умножены с использованием функции, приведенной в позапрошлом фрагменте кода. В результате, будет выведено значение 20. 

А что, если, например, нам понадобится умножить вместо двух чисел три? Если попробовать к функции добавить дополнительное число в примере, подобному тому, что выше, то будет выдана ошибка TypeError. 

def multiply(x, y):

    print (x * y)




multiply(5, 4, 3)




TypeError: multiply() takes 2 positional arguments but 3 were given

Если далее необходимо передать функции большее количество аргументов, то тогда можно использовать в качестве параметра *args.

Фактически код и функция будут теми же самыми. Просто вместо двух аргументов, которые были в изначальной функции, будут использоваться множественные, выраженные в *args

def multiply(*args):

    z = 1

    for num in args:

        z *= num

    print(z)




multiply(4, 5)

multiply(10, 9)

multiply(2, 3, 4)

multiply(3, 5, 10, 6)

И теперь попробуем запустить этот код, чтобы получать полное представление, что делает эта программа.

20

90

24

900

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

20

90

24

900

Благодаря тому, что нами был использован параметр *args при определении функции, у нас теперь появляется возможность передать такое количество аргументов, сколько будет нужно. Удобно, не так ли?

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

**kwrgs – что это за форма и для чего используется

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

Здесь звездочки также необходимо использовать, поскольку само слово, которое лежит в основе названия, является идиомой. 

Если говорить еще проще, то эта форма используется для передачи последовательности ключевое слово-значение. А чтобы стало еще более понятно, давайте приступим к рассмотрению примеров. 

def print_kwargs(**kwargs):

        print(kwargs)

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

python print_kwargs.py




{'kwargs_1': 'Shark', 'kwargs_2': 4.5, 'kwargs_3': True}

Обратите внимание! В качестве объекта, который выводится после использования этого ключевого слова, используется словарь с четко определенными значениями. Что касается последовательности, в котором элементы представленными, он может быть как упорядоченным, так и неупорядоченным.

В зависимости от того, какая версия Python используется, словарь может быть как упорядоченным, так и нет. Если у вас версия языка начинается 3,6 и больше, то тогда список будет упорядоченным. То есть, в том порядке, в котором осуществляется передача ключа и значения функции, в том и будет осуществляться вывод словаря. А вот в меньших версиях порядок будет случайным. 

Необходимо также учесть, что здесь происходит создания словаря, называющегося kwargs, и работа с ним абсолютно не отличается от любых других словарей.

Давайте создадим еще одно небольшое приложение, которое демонстрирует особенности использования **kwargs. Давайте попробуем создать функцию приветствия для словаря с именами. Попробуем начать со словаря, в котором есть два имени. 

def print_values(**kwargs):

    for key, value in kwargs.items():

        print("Значение для {} является {}".format(key, value))




print_values(my_name="Sammy", your_name="Casey")

После того, как будет запущен этот код, будет выдан следующий результат.

Значение для my_name является Sammy

Значение для your_name является Casey

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

А теперь давайте осуществим передачу дополнительных аргументов для функции, чтобы вы убедились в том, что принимается такое количество аргументов, которое требуется. 

def print_values(**kwargs):

    for key, value in kwargs.items():

        print("Значение для {} является {}".format(key, value))




print_values(

            name_1="Alex",

            name_2="Gray",

            name_3="Harper",

            name_4="Phoenix",

            name_5="Remy",

            name_6="Val"

        )

А после того, как мы запустим это приложение, у нас будет такой вывод.

Значение для name_1 является Alex

Значение для name_2 является Gray

Значение для name_3 является Harper

Значение для name_4 является Phoenix

Значение для name_5 является Remy

Значение для name_6 является Val

Преимущество параметра **kwargs в том, что появляется гибкость при использовании аргументов с ключевыми словами в программе. Когда нами используется в качестве параметра **kwargs, то знать, сколько аргументов в итоге будет передано, вовсе не нужно.

В каком порядке располагаются аргументы внутри функции?

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

Сначала необходимо размещать формально позиционные аргументы, потом *args, затем аргументы с ключевыми словами и **kwargs.

Тем не менее, в процессе работы с позиционными параметрами совместно с *args, **kwargs, функция будет объявляться приблизительно так. 

def example(arg_1, arg_2, *args, **kwargs):

    ...

Конечно, это общий шаблон. Вы можете прописывать собственное имя переменной, аргументы в зависимости от задач, которые вы перед собой ставите.

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

def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs):

    ...

Конечно, необходимо учитывать порядок, в котором будут располагаться аргументы в процессе создания функции. В ином случае есть большой риск получить ошибку синтаксиса.

Применение *args и **kwargs в процессе вызова функции

Чтобы передавать аргументы функции, также возможно использование *args и **kwargs

Сперва давайте рассмотрим пример со *args. 

def some_args(arg_1, arg_2, arg_3):

    print("arg_1:", arg_1)

    print("arg_2:", arg_2)

    print("arg_3:", arg_3)




args = ("Sammy", "Casey", "Alex")

some_args(*args)

В приведенной выше функции есть три параметра, которые определяются, как arg_1, arg_2, arg_3. Все эти три аргумента выводятся функцией. После этого в данном коде создается переменная, которой присваивается кортеж (вместо него может использоваться только одна итерация), и эта переменная может быть передана в функцию, если использовать дополнительные параметры со звездочкой.

Если вы запускаете приложение с использованием команды some_args.py, то наш результат в выводе будет следующим.

arg_1: Sammy

arg_2: Casey

arg_3: Alex

Помимо этого, мы можем внести изменения в код выше для того, чтобы сделать итерацию списка с другим названием переменной. Помимо этого, давайте объединим синтаксис *args с именованным параметром.  

def some_args(arg_1, arg_2, arg_3):

    print("arg_1:", arg_1)

    print("arg_2:", arg_2)

    print("arg_3:", arg_3)




my_list = [2, 3]

some_args(1, *my_list)

После того, как мы запустим приложение, получим такой результат.

arg_1: 1

arg_2: 2

arg_3: 3

Что касается аргументов **kwargs, то они работают аналогично, по факту. 

Заключение

Таким образом, аргументы со звездочкой (*args, *kwargs) открывают разработчикам дополнительные возможности в тех ситуациях, когда требуется передать сразу несколько аргументов. 

Использовать их, как оказывается, вовсе несложно. Достаточно соблюдать простой синтаксис и последовательность чередования аргументов, привязанных к месту в перечне и тех. которые не являются привязанными. И, естественно, *args могут использоваться в конце.

А так эта тема вовсе не сложная, не так ли?

ОфисГуру
Adblock
detector