Как использовать *args и **kwargs в Python

Введение
В Python функции могут принимать три типа аргументов: стандартные (фиксированные), переменные позиционные (args) и переменные именованные (kwargs). Стандартные аргументы просты, но ограничены по количеству. args и kwargs делают функции гибкими — они принимают переменное число входов.
Выбор способа передачи аргументов зависит от назначения функции и стиля кодирования.
Краткое напоминание о базовых функциях
Простейшая функция объявляет фиксированное количество аргументов:
def addnum(a, b, c):
return a + b + cТакой подход работает, но ограничен: функция принимает ровно три аргумента. Передача меньше или больше аргументов вызывает TypeError. Создавать отдельную функцию для каждой длины входных данных неудобно и не масштабируется.
Что такое *args
args — это соглашение: звёздочка () перед именем параметра собирает все дополнительные позиционные аргументы в кортеж.
Ключевая мысль: имя параметра может быть любым, важна звёздочка. Параметр собирает доп. позиционные аргументы, особенно удобен для однотипных значений (например, числа для суммирования).
Пример использования *args
def addnum(*args):
total = 0
for num in args:
total += num
return total
print(addnum(10, 1, 12, 12, 4, 54, 5)) # 98
print(addnum(14, 54, 5)) # 73
print(addnum(10, 5)) # 15*args внутри функции — обычный кортеж, поэтому с ним работают все операции кортежей: индексация, срезы, перебор.
Распаковка при вызове
Если у вас есть список/кортеж, его можно распаковать в позиционные аргументы:
nums = [1, 2, 3, 4]
print(addnum(*nums)) # передаём как addnum(1,2,3,4)Что такое kwargs
kwargs собирает дополнительные именованные (keyword) аргументы в словарь (dict). Каждое имя становится ключом словаря, значение — соответствующим значением.
Опять же, имя параметра может быть любым; важны две звёздочки.
Пример использования kwargs
def weekly_attendance(weekdays): total_attendees = 0 for attendees in weekdays.values(): total_attendees += attendees return total_attendees print(weekly_attendance(monday=265, tuesday=698, wednesday=365, thursday=463, friday=234)) # 2025 print(weekly_attendance(monday=265, friday=234)) # 499 print(weekly_attendance(wednesday=365, thursday=463, friday=234)) # 1062
kwargs — это обычный словарь: можно проверять ключи, использовать .get(), обновлять и т.д.
Когда использовать args и когда *kwargs
- Используйте *args, если функция принимает множество однотипных позиционных значений (числа, строки).
- Используйте **kwargs, если каждому значению нужен понятный ключ или опция, когда порядок не важен.
- Можно комбинировать: def f(a, b=1, args, *kwargs): …
Важно: позиционные аргументы идут до , именованные — после. Порядок аргументов в объявлении должен быть: обязательные, необязательные с дефолтами, args, затем **kwargs.
Полезные паттерны и альтернативные подходы
- Передавать коллекцию вместо *args: если у вас уже есть список, передача его как единого аргумента (или явная распаковка) имеет смысл.
- Использовать typing для ясности API:
from typing import Any
def logger(*messages: str, meta: Any) -> None:
...- Для больших конфигураций лучше передать словарь/объект (dataclass) вместо нагромождения kwargs.
- functools.reduce или sum применимы для агрегирования коллекций: sum(args) вместо цикла для чисел.
Примеры: распаковка и комбинирование
def greet(greeting, *names, punctuation='!'):
for name in names:
print(f"{greeting}, {name}{punctuation}")
names = ["Alice", "Bob"]
more = ("Charlie",)
all_names = [*names, *more]
greet('Hello', *all_names, punctuation='.')
# Передача словаря как kwargs
opts = {'sep': ', ', 'end': '\n'}
print('a', 'b', 'c', **opts)Контрпримеры и когда это не сработает
- Нельзя использовать *args, если вы ждёте строго определённые именованные параметры; порядок важен и имена нужны.
- **kwargs не заменяет проверку входных данных: если пользователь ошибся в ключе, код внутри может молча проигнорировать значение.
- При слишком большом числе опций лучше определить структуру (dataclass, NamedTuple) — это даёт валидацию и автодополнение в IDE.
Важно: не используйте только args/*kwargs для «сокрытия» плохо спроектированных интерфейсов.
Мини-методология выбора аргументов
- Определите, нужен ли упорядоченный список однотипных значений — выберите *args.
- Нужна ли пара ключ–значение с семантикой — выберите kwargs.
- Если конфигурация сложна или требует валидации — используйте dataclass или явный объект.
- Документируйте, какие ключи допустимы в kwargs и какие типы ожидаются.
Критерии приёмки (тесты/acceptance)
- Функция корректно суммирует любое количество чисел: addnum( ) -> 0, addnum(1) -> 1, addnum(1,2,3) -> 6.
- Распаковка работает: addnum(*[1,2,3]) == addnum(1,2,3).
- **kwargs сохраняет ключи: weekly_attendance(monday=100)[‘monday’] не применяется — но weekly_attendance возвращает сумму правильно.
- Негативные тесты: лишние позиционные аргументы в функции с фиксированным набором должны давать TypeError.
Чек-листы по ролям
Разработчик:
- Явно документировать ожидаемые типы в args и *kwargs.
- Использовать аннотации типов и примеры использования.
Рецензент кода:
- Проверить, нет ли скрытой логики, зависимой от порядка в **kwargs.
- Убедиться, что при неожидаемых ключах функция не ломается silently.
Поддерживающий код:
- Добавить тесты на пустые, минимальные и большие наборы входов.
- Рассмотреть миграцию на dataclass при росте числа опций.
Шпаргалка и сниппеты
- *args собирает позиции в кортеж:
def f(a, *args):
# args — tuple- kwargs собирает именованные аргументы в словарь:
def f(kwargs): # kwargs — dict
- Распаковка списка и словаря при вызове:
f(*[1,2,3], **{'x': 1, 'y': 2})- Быстрая суммирующая реализация:
def addnum(*args):
return sum(args)Частые ошибки и как от них защититься
- Ошибка: ожидание конкретных ключей в **kwargs без проверки. Решение: использовать kwargs.get(‘key’, default) или проверить наличие ключа явно.
- Ошибка: мешать позиционные и именованные аргументы неправильно. Решение: придерживаться последовательности параметров, использовать явные имена при вызове.
- Ошибка: пытаться модифицировать tuple из *args напрямую. Решение: создать список list(args) если нужна мутабельность.
Ментальная модель
- Представляйте args как «корзину позиционных значений» (tuple); kwargs — как «словарь опций» (dict). Если нужен порядок — используйте args или коллекцию; если нужны имена — kwargs.
Простая диаграмма принятия решения (Mermaid)
flowchart TD
A[Нужно принять переменное число аргументов?] --> B{Аргументы именованные?}
B -- Да --> C[Использовать **kwargs]
B -- Нет --> D[Использовать *args]
C --> E[Подумать о dataclass для валидации]
D --> EСводка
args и kwargs — простые, но мощные механизмы для гибких функций. args удобно для набора однотипных позиционных значений (tuple), kwargs — для именованных опций (dict). Документируйте ожидаемые ключи/типы, добавляйте тесты и думайте о dataclass, если интерфейс становится сложным.
Ключевые идеи:
- *args = кортеж позиционных дополнительных аргументов.
- **kwargs = словарь именованных дополнительных аргументов.
- Распаковка коллекций упрощает вызовы: и *.
Спасибо за внимание — применяйте args и *kwargs осознанно, чтобы API оставались понятными и поддерживаемыми.
Похожие материалы
Как исправить ошибку Not designed to run on Windows
Галерея в Проводнике Windows 11: включение и инструкция
Скрыть раздел восстановления в Windows
Исправление проблем с wmiprvse.exe в Windows 10
Команда touch: метки времени и пустые файлы