Аргументы функции python словарь

Распаковка аргументов#

В Python выражения *args и **kwargs позволяют выполнять ещё одну задачу — распаковку аргументов.

До сих пор мы вызывали все функции вручную. И соответственно передавали все нужные аргументы.

В реальности, как правило, данные необходимо передавать в функцию программно. И часто данные идут в виде какого-то объекта Python.

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

Например, при форматировании строк часто надо передать методу format несколько аргументов. И часто эти аргументы уже находятся в списке или кортеже. Чтобы их передать методу format, приходится использовать индексы таким образом:

In [1]: items = [1,2,3] In [2]: print('One: <>, Two: <>, Three: <>'.format(items[0], items[1], items[2])) One: 1, Two: 2, Three: 3 

Вместо этого, можно воспользоваться распаковкой аргументов и сделать так:

In [4]: items = [1,2,3] In [5]: print('One: <>, Two: <>, Three: <>'.format(*items)) One: 1, Two: 2, Three: 3 

Еще один пример — функция config_interface (файл func_config_interface_unpacking.py):

In [8]: def config_interface(intf_name, ip_address, mask): ..: interface = f'interface intf_name>' ..: no_shut = 'no shutdown' ..: ip_addr = f'ip address ip_address> mask>' ..: result = [interface, no_shut, ip_addr] ..: return result ..: 

Функция ожидает такие аргументы:

Функция возвращает список строк для настройки интерфейса:

In [9]: config_interface('Fa0/1', '10.0.1.1', '255.255.255.0') Out[9]: ['interface Fa0/1', 'no shutdown', 'ip address 10.0.1.1 255.255.255.0'] In [11]: config_interface('Fa0/10', '10.255.4.1', '255.255.255.0') Out[11]: ['interface Fa0/10', 'no shutdown', 'ip address 10.255.4.1 255.255.255.0'] 

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

Например, список interfaces_info, в котором находятся параметры для настройки интерфейсов:

In [14]: interfaces_info = [['Fa0/1', '10.0.1.1', '255.255.255.0'], . : ['Fa0/2', '10.0.2.1', '255.255.255.0'], . : ['Fa0/3', '10.0.3.1', '255.255.255.0'], . : ['Fa0/4', '10.0.4.1', '255.255.255.0'], . : ['Lo0', '10.0.0.1', '255.255.255.255']] . : 

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

In [15]: for info in interfaces_info: . : print(config_interface(info)) . : --------------------------------------------------------------------------- TypeError Traceback (most recent call last) ipython-input-15-d34ced60c796> in module> 1 for info in interfaces_info: ----> 2 print(config_interface(info)) 3 TypeError: config_interface() missing 2 required positional arguments: 'ip_address' and 'mask' 

Ошибка вполне логичная: функция ожидает три аргумента, а ей передан 1 аргумент — список.

В такой ситуации пригодится распаковка аргументов. Достаточно добавить * перед передачей списка как аргумента, и ошибки уже не будет:

In [16]: for info in interfaces_info: . : print(config_interface(*info)) . : ['interface Fa0/1', 'no shutdown', 'ip address 10.0.1.1 255.255.255.0'] ['interface Fa0/2', 'no shutdown', 'ip address 10.0.2.1 255.255.255.0'] ['interface Fa0/3', 'no shutdown', 'ip address 10.0.3.1 255.255.255.0'] ['interface Fa0/4', 'no shutdown', 'ip address 10.0.4.1 255.255.255.0'] ['interface Lo0', 'no shutdown', 'ip address 10.0.0.1 255.255.255.255'] 

Python сам „распакует“ список info и передаст в функцию элементы списка как аргументы.

Таким же образом можно распаковывать и кортеж.

Распаковка ключевых аргументов#

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

Функция check_passwd (файл func_check_passwd_optional_param_2.py):

In [19]: def check_passwd(username, password, min_length=8, check_username=True): . : if len(password)  min_length: . : print('Пароль слишком короткий') . : return False . : elif check_username and username in password: . : print('Пароль содержит имя пользователя') . : return False . : else: . : print(f'Пароль для пользователя username> прошел все проверки') . : return True . : 

Список словарей username_passwd , в которых указано имя пользователя и пароль:

In [20]: username_passwd = ['username': 'cisco', 'password': 'cisco'>, . : 'username': 'nata', 'password': 'natapass'>, . : 'username': 'user', 'password': '123456789'>] 

Если передать словарь функции check_passwd, возникнет ошибка:

In [21]: for data in username_passwd: . : check_passwd(data) . : --------------------------------------------------------------------------- TypeError Traceback (most recent call last) ipython-input-21-ad848f85c77f> in module> 1 for data in username_passwd: ----> 2 check_passwd(data) 3 TypeError: check_passwd() missing 1 required positional argument: 'password' 

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

Если добавить ** перед передачей словаря функции, функция нормально отработает:

In [22]: for data in username_passwd: . : check_passwd(**data) . : Пароль слишком короткий Пароль содержит имя пользователя Пароль для пользователя user прошел все проверки In [23]: for data in username_passwd: . : print(data) . : check_passwd(**data) . : 'username': 'cisco', 'password': 'cisco'> Пароль слишком короткий 'username': 'nata', 'password': 'natapass'> Пароль содержит имя пользователя 'username': 'user', 'password': '123456789'> Пароль для пользователя user прошел все проверки 

Python распаковывает словарь и передает его в функцию как ключевые аргументы. Запись check_passwd(**data) превращается в вызов вида check_passwd(username=’cisco’, password=’cisco’) .

Источник

Аргументы функции python словарь

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

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

Оператор * применяется с любым итерируемым объектом (например, кортежем, списком и строками). Тогда как оператор ** можно использовать только со словарями.

*args

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

def fun(*args): # обращаемся к первому элементу кортежа print(args[0]) # выводим весь кортеж print(args) fun("Python", "C++", "Java", "C#")

Здесь функция fun принимает кортеж значений. При вызове мы можем передать ей различное количество значений. Так, в примере выше передается четыре строки, которые образуют кортеж. Консольный вывод программы:

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

def sum(*args): result = 0 for arg in args: result += arg return result print(sum(1, 2, 3)) # 6 print(sum(1, 2, 3, 4)) # 10 print(sum(1, 2, 3, 4, 5)) # 15

Оператор **

Оператор ** упаковывает аргументы, переданные по имени, в словарь. Имена параметров служат ключами. Например, определим функцию, которая просто будет выводить все переданные параметры

def fun(**kwargs): print(kwargs) # выводим словарь на консоль fun(name="Tom", age="38", company="Google") fun(language="Python", version="3.11")

Консольный вывод программы:

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

def fun(**kwargs): for key in kwargs: print(f" = ") fun(name="Tom", age="38", company="Google")

Консольный вывод программы:

name = Tom age = 38 company = Google

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

Выше было описано, как операторы * и ** применяются для упаковки аругментов в кортеж и словарь соответственно. Но эти же операторы могут использоваться для распаковки.

Оператор * и распаковка

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

def sum(*args): result = 0 for arg in args: result += arg return result numbers = (1, 2, 3, 4, 5) print(sum(numbers))

Здесь в вызов функции sum передается кортеж. Параметр *args по сути тоже представляет кортеж, и кажется, все должно работать. Тем не менее мы столкнемся с ошибкой

TypeError: unsupported operand type(s) for +=: 'int' and 'tuple'

То есть в данном случае кортеж numbers передается как элемент кортежа *args .

И чтобы элементы кортежа были переданы в кортеж *args как отдельные значения, необходимо выполнить их распаковку:

def sum(*args): result = 0 for arg in args: result += arg return result numbers = (1, 2, 3, 4, 5) # применяем распаковку - *numbers print(sum(*numbers)) # 15

Здесь при передачи кортежа numbers в функцию sym применяется распаковка: *numbers

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

def print_person(name, age, company): print(f"Name:, Age: , Company: ") person =("Tom", 38, "Google") # выполняем распаковку кортежа person print_person(*person) # Name:Tom, Age: 38, Company: Google

В данном случае выражение *person раскладывает кортеж person на отдельные значения, которые передаются параметрам name, age и company.

Оператор ** и распаковка

Оператор ** применяется для распаковки словарей:

def print_person(name, age, company): print(f"Name:, Age: , Company: ") tom = # выполняем распаковку словаря tom print_person(**tom) # Name:Tom, Age: 38, Company: Google

Здесь выражение **tom раскладывает словарь на отдельные значения, которые передаются параметрам name, age и company по названию ключей.

Сочетание параметров

Параметры *args и *kwargs могут использоваться в функции вместе с другими параметрами. Например:

def sum(num1, num2, *nums): result=num1+num2 for n in nums: result += n return result print(sum(1,2,3)) # 6 print(sum(1,2,3,4)) # 10

Источник

Читайте также:  Birthday Reminders for August
Оцените статью