[Python] Хватит злоупотреблять *args и **kwargs в Python (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Photo by Matthew Henry on UnsplashДа будет холивар! Использовать args/kwargs или не использовать, это показатель профессионализма или базовые знания, без которых должно быть стыдно? Часто листая github различных проектов натыкаешься на наличие данных аргументов в функциях просто потому что. И данная статья натолкнула на пообщаться на эту тему. Вообще, стараюсь не использовать неконтролируемое аргументирование на практике, но на сколько это вообще распространенный метод программирования? Делитесь в комментариях. И приятного чтения. В Интернете полно обучалок, которые научат вас использовать *args и **kwargs при определении функции в Python. Возможно, вы уже часами пытаетесь понять, как раскрыть их потенциал. Может быть, после всего этого исследования вы теперь чувствуете в них уверенность.Не надо!Мощные инструменты опасны. Вы могли облегчить свою жизнь, но запомните мои слова, они вскоре вернутся, чтобы преследовать вас.Но почему?Немного основПараметры в Python функции могут принимать два типа аргументов:
- Позиционные аргументы, которые передаются позиционно.
- Именованные аргументы, которые передаются с ключевыми словами.
def foo(start, end):
print(start, end)
Например, foo ('Hi', end = 'Bye!') Передает позиционный аргумент "Hi" и именованный аргумент "Bye!", где ключевым словом выступает end для функции foo. Параметры функции предопределены; количество параметров, принимаемых в функции, фиксировано. Однако это не всегда так.*args позволяет передавать вашей функции произвольное количество позиционных аргументов. Звездочка * - параметр распаковки. Параметры упаковываются в виде итерируемого кортежа внутри функции.
def foo(*args):
print(type(args))
for arg in args:
print(arg)
foo(1, 2, 'end')
# <class 'tuple'>
# 1
# 2
# end
С другой стороны, **kwargs позволяет передавать вашей функции произвольное количество аргументов с ключевыми словами. Поскольку у каждого именованного аргумента есть ключевое слово и значение, он сгруппирован как итерируемый словарь внутри функции.
def foo2(**kwargs):
print(type(kwargs))
for keyword, value in kwargs.items():
print(f'{keyword}={value}')
foo2(a=1, b=2, z='end')
# <class 'dict'>
# a=1
# b=2
# z=end
Photo by Susan Holt Simpson on UnsplashПроблемаВ большинстве случаев вам действительно не нужны *args и **kwargs. Как часто вы не знаете, сколько аргументов должна получить предопределенная ВАМИ функция?Код гораздо сложнее отлаживать, если вы злоупотребляете в нем подобными решениями, потому что вы позволяете передавать произвольное количество аргументов функции, и функция может вести себя непредсказуемо.
Явное лучше, чем неявное. - Дзен Python
Когда всё-таки использовать аргументы?Если кратко: используйте их, когда они вам действительно нужны. Например, функция с множеством необязательных полей, и некоторые из них используются только в редких ситуациях. Скажем, функция строит график, и вы можете передавать различные необязательные аргументы, чтобы изменить его цвет, стиль, размер и т.д.Каждый раз, когда вы используете *args и/или **kwargs, убедитесь, что вы пишите к функциям ясную документацию, чтобы избежать путаницы.Есть один сценарий, в котором их использование может быть неизбежным. Если вы создаете оболочку для функции с неизвестными аргументами, вам нужно будет принять произвольное количество позиционных и именованных аргументов, а затем передать их функции.Например, декораторы в Python работают как оболочки, которые изменяют поведение кода, не изменяя сам код функции, тем самым расширяя дополнительные функции.
Photo by Alexander Schimmeck on UnsplashВ следующем примере мы создаем трассировку, которая выводит имя выполняемой функции в качестве проверки работоспособности. Декоратор применяется к функции с помощью @trace поверх функции, как показано ниже. Поскольку мы хотим применить этот декоратор к любым функциям с любым количеством аргументов, нам нужно использовать *args и **kwargs.
def trace(func):
def print_in(*args, **kwargs):
print('Executing function', func.__name__)
return func(*args, **kwargs)
return print_in
@trace
def calc(a,b):
print(f'a+b is {a+b}, a-b is {a-b}.')
calc(1,2)
# Executing function calc
# a+b is 3, a-b is -1.
@trace
def add_all(*args):
print(reduce(lambda a,b:a+b, args))
a = add_all(1,2,3,4,5)
# Executing function add_all
# 15
ВыводыПо возможности избегайте их.Обратите внимание, что args и kwargs так называются просто по соглашению. Вы можете называть их как хотите. Именно звездочки * и ** дают функциям ту самую мощь.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Eden Au
===========Похожие новости:
- [Высокая производительность, Разработка веб-сайтов, Python, Django, Flask] Ещё раз о производительности фреймворков Python для веб разработки
- [Поисковые технологии, Python, Разработка мобильных приложений, Kotlin] Не баян: ищем дубликаты изображений на основе Milvus с индексом FAISS внутри
- [Open source, Python, IT-инфраструктура, Хранение данных, Хранилища данных] HDB++ TANGO Archiving System
- [Python, Data Mining, Хакатоны, Машинное обучение, Natural Language Processing] Sibur Challenge 2020 или «как мы фичи придумывали»
- [Python, Rust] Rust глазами Python-разработчика
- [Информационная безопасность, Python, CTF] HackTheBox. Прохождение Laser. Jetdirect, RPC и кража SSH
- [Python, Программирование, Профессиональная литература] Классические задачи Computer Science на языке Python. Обзор книги (перевод)
- [Python, Визуализация данных, Машинное обучение] Мы скачали 10 миллионов Jupyter-ноутбуков с Github — и вот что мы выяснили
- [Python, Scala, Big Data] Big Data Tools EAP 12 Is Out: Experimental Python Support and Search Function in Zeppelin Notebooks
- [Python, IT-инфраструктура, Администрирование баз данных, DevOps, Микросервисы] Vault+Pydantic: продолжение саги, локальная разработка
Теги для поиска: #_python, #_python3, #_python
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:50
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Photo by Matthew Henry on UnsplashДа будет холивар! Использовать args/kwargs или не использовать, это показатель профессионализма или базовые знания, без которых должно быть стыдно? Часто листая github различных проектов натыкаешься на наличие данных аргументов в функциях просто потому что. И данная статья натолкнула на пообщаться на эту тему. Вообще, стараюсь не использовать неконтролируемое аргументирование на практике, но на сколько это вообще распространенный метод программирования? Делитесь в комментариях. И приятного чтения. В Интернете полно обучалок, которые научат вас использовать *args и **kwargs при определении функции в Python. Возможно, вы уже часами пытаетесь понять, как раскрыть их потенциал. Может быть, после всего этого исследования вы теперь чувствуете в них уверенность.Не надо!Мощные инструменты опасны. Вы могли облегчить свою жизнь, но запомните мои слова, они вскоре вернутся, чтобы преследовать вас.Но почему?Немного основПараметры в Python функции могут принимать два типа аргументов:
def foo(start, end):
print(start, end) def foo(*args):
print(type(args)) for arg in args: print(arg) foo(1, 2, 'end') # <class 'tuple'> # 1 # 2 # end def foo2(**kwargs):
print(type(kwargs)) for keyword, value in kwargs.items(): print(f'{keyword}={value}') foo2(a=1, b=2, z='end') # <class 'dict'> # a=1 # b=2 # z=end Photo by Susan Holt Simpson on UnsplashПроблемаВ большинстве случаев вам действительно не нужны *args и **kwargs. Как часто вы не знаете, сколько аргументов должна получить предопределенная ВАМИ функция?Код гораздо сложнее отлаживать, если вы злоупотребляете в нем подобными решениями, потому что вы позволяете передавать произвольное количество аргументов функции, и функция может вести себя непредсказуемо. Явное лучше, чем неявное. - Дзен Python
Photo by Alexander Schimmeck on UnsplashВ следующем примере мы создаем трассировку, которая выводит имя выполняемой функции в качестве проверки работоспособности. Декоратор применяется к функции с помощью @trace поверх функции, как показано ниже. Поскольку мы хотим применить этот декоратор к любым функциям с любым количеством аргументов, нам нужно использовать *args и **kwargs. def trace(func):
def print_in(*args, **kwargs): print('Executing function', func.__name__) return func(*args, **kwargs) return print_in @trace def calc(a,b): print(f'a+b is {a+b}, a-b is {a-b}.') calc(1,2) # Executing function calc # a+b is 3, a-b is -1. @trace def add_all(*args): print(reduce(lambda a,b:a+b, args)) a = add_all(1,2,3,4,5) # Executing function add_all # 15 =========== Источник: habr.com =========== =========== Автор оригинала: Eden Au ===========Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:50
Часовой пояс: UTC + 5