Что такое параметры функции в 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 могут использоваться в конце.
А так эта тема вовсе не сложная, не так ли?