Цель: выделить разницу между именованными аргументами и **kwargs
при разработке методов в Python.
Рассмотрим следующее требование для создания функции для вашего сервиса:
- Создайте метод для создания запроса БД
SELECT
в таблице пользователей, где вам нужно следующееparams
от пользователя вашего метода: schema
: для простоты доступны две схемы:company
иclient
, где по умолчанию, если пользователь не предоставляет схему, по умолчанию должна быть схемаclient
.dept
: описание отдела, по которому запросSELECT
должен фильтровать пользователей, и, если он не указан,dept
по умолчанию должен быть равенIT
.- Пользователь может указать дополнительные критерии фильтрации, которые повлияют на
SELECT
структуру запроса.
Теперь, основываясь на вышеуказанных требованиях, вы можете использовать любой из следующих двух методов:
Примечание. Проверка данных и обеспечение безопасности запроса здесь не рассматриваются, но это очень важно. Возможно, я добавлю больше статей на эту тему позже.
Основываясь на первом взгляде на две вышеупомянутые функции, можно подумать, что использование method2
будет оптимальным, и обоснование основано на:
- Пользователь
method2
явно будет иметь представление о том, какойnamed arguments
метод ожидает, а также о значениях по умолчанию, назначенных этимargs
. - Код лаконичен и элегантен.
Но это может быстро стать самоуверенным, и у меня есть следующие контраргументы:
method2
не является явным победителем, потому что добавление некоторой документации в форме, распознаваемой IDE (например,reStructuredText
), будет достаточно умным, чтобы рекомендовать вам, какой**kwargs
метод ожидает. Например, быстро наведите указатель мыши на метод, и вы получите полную документацию. Некоторые движки с поддержкой интеллектуального ИИ, такие как Kite, также могут автоматически заполнять сигнатуру вызова метода. Следовательно, преимущества, упомянутые в пункте 1 выше, являются, как выразился Джоуи, шуткой.method2
трудно расширить. Если параметр чаще используется всеми пользователями метода, и если вам также нужно сделать его одним из именованных аргументов, то в конечном итоге вы перекомпилируете свою часть кода (это особенно важно, если ваш код будет использоваться в качестве библиотеки вместо общей кодовой базы).
Учитывая это, нет никакого реального преимущества в использовании method2
, за исключением экономии нескольких строк кода, что на самом деле здорово, и его все же следует использовать, а не просто использовать **kwargs
. Но поскольку мы обсуждаем плюсы обоих подходов, вот преимущество использования **kwargs
:
- Это предотвращает предоставление методу случайных значений
None
. Например, запрос, сгенерированныйmethod1(schema=None, dest=None, **kwargs)
иmethod2(schema=None, dest=None, **kwargs)
, будет другим.method1
в своей текущей форме выполняет дополнительные проверки, чтобы убедиться, что предоставленное значение не является пустым. И да, это также можно сделать вmethod2
, но тогда он потеряет преимущество краткости и элегантности.
На этом этапе можно было бы прийти к выводу об использовании лучшего из обоих миров, и да, это было целью этой статьи. Хорошо написанная функция Python будет использовать named arguments
вместе с соответствующими проверками предоставленных значений, например:
Надеюсь, вам понравилась статья! Это моя первая статья на Medium, и, надеюсь, впереди еще много.