Автостопом по Python | страница 40
Зачастую сложнее удалить опциональный аргумент (и логику внутри функции), который был добавлен на всякий случай и, казалось бы, никогда не используется, чем ввести новый необязательный аргумент и его логику в тот момент, когда они действительно нужны.
• Список с произвольным количеством аргументов. Такой список определяется с помощью конструкции *args, которая указывает на произвольное количество позиционных аргументов. В теле функции args будет играть роль кортежа, состоящего из всех оставшихся позиционных аргументов. Например, функция send(message, *args) также может быть вызвана, когда каждый получатель будет представлен отдельным аргументом: send("42", "Frankie", "Benjy", "Trillian"). В теле функции конструкция args будет равна выражению ("Frankie", "Benjy", "Trillian"). Хороший пример, иллюстрирующий этот подход, — функция print.
Подводный камень: если функция получает список аргументов одного вида, более понятным будет использование списка или любой другой последовательности. Если функция send в этом примере принимает несколько получателей, мы определим ее явно как send(message, recipients) и будем вызывать как send("42", ["Benjy", "Frankie", "Trillian"]).
• Словарь с произвольным количеством аргументов с ключевым словом. Такой словарь определяется с помощью конструкции **kwargs, которая указывает на произвольное количество именованных аргументов. В теле функции kwargs будет словарем, содержащим все переданные именованные аргументы, которые не были «пойманы» другими аргументами с ключевым словом в сигнатуре функции. Это может быть полезно при журналировании. Средства форматирования на разных уровнях могут принять необходимую им информацию, минуя пользователя.
Подводный камень: эти мощные приемы нужно применять только в том случае, когда это действительно необходимо. Если же имеется более простая и прозрачная конструкция, то для выражения предназначения функции следует выбрать именно ее.
Имена переменных *args и **kwargs могут (и должны быть) заменены другими, если это более информативно.
Какие аргументы станут позиционными, а какие — необязательными, зависит только от программиста, который пишет функцию. От него также зависит наличие передачи произвольного количества аргументов. В конце концов, должен существовать один (предпочтительно всего один) очевидный способ это сделать. Другие пользователи оценят ваши усилия, если функции, написанные на Python: