*args **kwargs Python

Содержание
Введение
*args
**kwargs
*args, **kwargs
Фильтрация **kwargs
Похожие статьи

Введение

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

Это очень удобно, к тому же есть два варианта: обычный - через *args и через ключевые слова - **kwargs.

Начнём с *args

*args

Рассморим скрипт args_demo.py

def myfunc(*args): print(args) myfunc(50,70,120,3,14) myfunc('a','a','a')

python args_demo.py

(50,70,120,3,14)
('a', 'b','c')

Как видно из примера: одна и та же функция смогла обработать сперва пять аргументов типа int а затем три аргумента типа str

Ничто не мешает перебрать полученные аргументы по одному.

Воспользуемся циклом for

def myfunc(*args): for item in args: print(item) myfunc(50,70,120,3,14) myfunc('a','a','a')

python args_demo.py

50
70
120
3
14
a
b
c

**kwargs

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

Это очень удобно, если вам нужно работать с разными пользовательскими сценариями - не нужно вводить какой-то определённый порядок аргументов, как в Bash скриптах

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

Методы

Существуют встроенные методы для работы с kwargs

Начнём с методов keys() и values() которые возвращают имя ключа и значение.

Вызовем функцию filterkw() с тремя аргументами-ключами a=1, b=2, c=3 и выведем их в терминал отдельно друг от друга

def filterkw(**kwargs): for k in kwargs.keys(): print(f"key: {k}") for v in kwargs.values(): print(f"value: {v}") if __name__ == "__main__": filterkw(a=1, b=2, c=3)

key: a key: b key: c value: 1 value: 2 value: 3

Метод get() возвращает значение по ключу

def filterkw(**kwargs): filters = ["b", "c"] for f in filters: print(kwargs.get(f)) if __name__ == "__main__": filterkw(a=1, b=2, c=3)

2 3

Если такого ключа нет get() возвращает None

def filterkw(**kwargs): filters = ["b", "c", "z"] for f in filters: print(kwargs.get(f)) if __name__ == "__main__": filterkw(a=1, b=2, c=3)

2 3 None

Пример

Рассморим скрипт kwargs_demo.py

def myfunc(**kwargs): if 'website' in kwargs: print('Заходите на сайт {}'.format(kwargs['website'])) else: print('Посетите topbicycle.ru') myfunc(website='HeiHei.ru') myfunc(localsite='aredel.com') myfunc(website='eth1.ru', author='Andrey Olegovich')

python kwargs_demo.py

Заходите на сайт HeiHei.ru
Посетите topbicycle.ru
Заходите на сайт eth1.ru

Функция ожидает аргумент с ключом website

При первом вызове такой аргумент приходит один

Во втором вызове не приходит ключа website и срабатывает else

Во время третьего вызова приходи website и author, но author функция не ждёт и он просто игнорируется

Добавим ещё один вызов функции

myfunc(website='eth1.ru', author='Andrey Olegovich', 2)

python kwargs_demo.py

File "args_demo.py", line 29 myfunc3(website='eth1.ru', author='Andrey Olegovich', 2) SyntaxError: non-keyword arg after keyword arg

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

*args **kwargs

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

Рассморим скрипт args_kwargs_demo.py

def myfunc(*args,**kwargs): if 'website' in kwargs: print('Заходите на сайт {}'.format(kwargs['website'])) else: print('Посетите topbicycle.ru') myfunc(2, website='eth1.ru', author='Andrey Olegovich')

python args_kwargs_demo.py

Заходите на сайт eth1.ru

Если вы получили ошибку

File "args_demo.py", line 21 SyntaxError: Non-ASCII character '\xd0' in file args_demo.py on line 21, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Добавьте следующий код на первую строку

# coding=utf-8

Подробности здесь

Фильтрация **kwargs

Иногда бывает нужно проводить действия только с определёнными keyword аргументами.

Остальные нужно отфильтровать. О том как это сделать с помощью генератора списоков (list comprehension) вы узнаете в этом параграфе.

Предположим функция filterkw() принимает **kwargs.

Создадим список нужных и будем выводить на экран только их.

def filterkw(**kwargs): filters = ["limit", "offset", "sortkey", "sortdir"] params = {k: kwargs[k] for k in filters if k in kwargs.keys()} print(params) if __name__ == '__main__': filterkw(test=2, more=3, new=40) filterkw(limit=25, some=50, offset=40) filterkw(limit=1, offset=2, sortkey=90, sortdir=100)


{'limit': 25, 'offset': 40}
{'limit': 1, 'offset': 2, 'sortkey': 90, 'sortdir': 100}

Первый вызов ни к чему не привёл, так как ни test, ни more, ни new не являются нужными ключами.

Второй вызов содержал два нужных ключа limit и offset. some был проигнорирован

Третий вызов содержал все нужные ключи и они все были выведены на экран

Похожий пример с использоанием get

def filterkw(**kwargs): filters = ["a", "e", "i", "o"] params = {k: kwargs.get(k) for k in filters if kwargs.get(k)} print(params) if __name__ == "__main__": filterkw(a=1, b=2, c=3, d=4, e=5)

python list_comp_filter.py

{'a': 1, 'e': 5}

Если вам интересна тема вызова скриптов с аргументами из командной строки - рекомендую:

Похожие статьи
Интерактивный режим
str: строки
\: перенос строки
Списки []
if, elif, else
Циклы
Функции
try except
Пакеты
*args **kwargs
ООП
enum
Опеределить тип переменной Python
Тестирование с помощью Python
Работа с REST API на Python
Файлы: записать, прочитать, дописать, контекстный менеджер…
Скачать файл по сети
SQLite3: работа с БД
datetime: Дата и время в Python
json.dumps
Selenium + Python
Сложности при работе с Python
DJANGO
Flask
Скрипт для ZPL принтера
socket :Python Sockets
Виртуальное окружение
subprocess: выполнение bash команд из Python
multiprocessing: несколько процессов одновременно
psutil: cистемные ресурсы
sys.argv: аргументы командной строки
PyCharm: IDE
pydantic: валидация данных
paramiko: SSH из Python
enumerate
logging: запись в лог
Обучение программированию на Python