Порядок аргументов ключевых слов в вызове функции

Порядок аргументов ключевых слов в вызове функции
Порядок аргументов ключевых слов в вызове функции - davidclode @ Unsplash

В некоторых языках, таких как Python, порядок аргументов ключевых слов в вызове функций не имеет значения. Но существует ли лучшая практика для этого?

Например, предположим, что сигнатура функции def foo(bar, baz, qux).

Конечно, foo(bar=3, baz=8, qux=9) - это то же самое, что и foo(qux=9, bar=3, baz=8). Но разве первое не легче читать человеку, который одновременно обращается к документации?

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

Первая версия

foo(qux=10, bar=9, baz=8)
# (...)
foo(baz=8, qux=10, bar=8)

Здесь мы видим, что единственное различие между двумя вызовами - это значение bar, но для того, чтобы это понять, требуется доля секунды.

Вторая версия

foo(bar=9, baz=8, qux=10)
# (...)
foo(bar=8, baz=8, qux=10)

Здесь, на мой взгляд, проще сравнить два вызова.

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

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

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

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

Я бы утверждал, что именованные аргументы существуют в первую очередь для того, чтобы повысить явность кода (особенно когда речь идет о методах, принимающих несколько или более параметров), и чтобы позволить пропускать/исключать необязательные параметры, оставляя их имена без внимания. Эти две потребности/выгоды в первую очередь оправдывают существование синтаксиса именованных аргументов.

Возможность фактически изменить порядок аргументов, указав их имена в другом порядке, является, на мой взгляд, побочной функцией и будет использоваться крайне редко.

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

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


LetsCodeIt, 21 апреля 2023 г., 12:55

Похожие посты

Какова хорошая стратегия модульного тестирования цепочки вызовов публичных методов?Хранение нескольких экземпляров на синглтоне?Является ли добавление функций в пространство имен/модуль после импорта антипаттерном?Для работы с константами, которые используются совместно в нескольких пакетах?Дизайн программного обеспечения: разделение при сильной зависимости от сторонней библиотекиПочему сильно объектно-ориентированные языки избегают использования функций в качестве примитивного типа?В чем разница между KPI и SLI, если она есть?Является ли извлечение интерфейса только для целей тестирования запахом кода?При моделировании требований как изобразить атрибуты диаграммы классов, допустимые значения которых определены пользователем и имеют конечное число?Сегодня я написал "тесты" для тестового кода. Это было правильно? Это запах?