Цель: выделить разницу между именованными аргументами и **kwargs при разработке методов в Python.

Рассмотрим следующее требование для создания функции для вашего сервиса:

  • Создайте метод для создания запроса БД SELECT в таблице пользователей, где вам нужно следующее params от пользователя вашего метода:
  • schema: для простоты доступны две схемы: company и client, где по умолчанию, если пользователь не предоставляет схему, по умолчанию должна быть схема client.
  • dept : описание отдела, по которому запрос SELECT должен фильтровать пользователей, и, если он не указан, dept по умолчанию должен быть равен IT.
  • Пользователь может указать дополнительные критерии фильтрации, которые повлияют на SELECT структуру запроса.

Теперь, основываясь на вышеуказанных требованиях, вы можете использовать любой из следующих двух методов:

Примечание. Проверка данных и обеспечение безопасности запроса здесь не рассматриваются, но это очень важно. Возможно, я добавлю больше статей на эту тему позже.

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

  1. Пользователь method2 явно будет иметь представление о том, какой named argumentsметод ожидает, а также о значениях по умолчанию, назначенных этим args.
  2. Код лаконичен и элегантен.

Но это может быстро стать самоуверенным, и у меня есть следующие контраргументы:

  • 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, и, надеюсь, впереди еще много.