*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}
Если вам интересна тема вызова скриптов с аргументами из командной строки - рекомендую: