👩💻 *args и **kwargs: гибкие параметры без боли
Иногда ты не знаешь заранее, сколько аргументов получит твоя функция. Python даёт тебе две магические конструкции для таких случаев — *args и **kwargs.
📌*args собирает все позиционные аргументы в кортеж:
def add_all(*args):
return sum(args)
add_all(1, 2, 3) # ➡️ 6
📌 **kwargs собирает все именованные аргументы в словарь:
def print_config(**kwargs):
for k, v in kwargs.items():
print(f"{k} = {v}")
print_config(debug=True, timeout=10)
# ➡️ debug = True
# ➡️ timeout = 10
🔥Комбинируем всё:
def func(a, b, *args, **kwargs):
pass
➡️ a и b — обязательные, args — остальные позиционные, kwargs — именованные.
🧠 Применения:
1. Проксирование аргументов
Ты вызываешь другую функцию, не зная её сигнатуру:
def wrapper(*args, **kwargs):
return real_func(*args, **kwargs)
2. Гибкий API без переписывания сигнатур
Вместо:
def create_user(name, email, age, is_admin=False):
...
Можно:
def create_user(**kwargs):
...
3. Расширение без поломки интерфейса
У тебя есть базовый метод:
def process(data, **kwargs):
...
➡️ В будущем можно спокойно добавить флаги, не меняя вызовы.
🗣️ Запомни: *args и **kwargs — это про гибкость и масштабируемость. Главное — использовать их осознанно: когда действительно нужно, а не “на всякий случай”.
📍Где применяется:
Декораторы, middleware, логгеры, фреймворки (Django, Flask), адаптеры, кастомные API, генераторы CLI-интерфейсов.
Иногда ты не знаешь заранее, сколько аргументов получит твоя функция. Python даёт тебе две магические конструкции для таких случаев — *args и **kwargs.
📌*args собирает все позиционные аргументы в кортеж:
def add_all(*args):
return sum(args)
add_all(1, 2, 3) # ➡️ 6
📌 **kwargs собирает все именованные аргументы в словарь:
def print_config(**kwargs):
for k, v in kwargs.items():
print(f"{k} = {v}")
print_config(debug=True, timeout=10)
# ➡️ debug = True
# ➡️ timeout = 10
🔥Комбинируем всё:
def func(a, b, *args, **kwargs):
pass
➡️ a и b — обязательные, args — остальные позиционные, kwargs — именованные.
🧠 Применения:
1. Проксирование аргументов
Ты вызываешь другую функцию, не зная её сигнатуру:
def wrapper(*args, **kwargs):
return real_func(*args, **kwargs)
2. Гибкий API без переписывания сигнатур
Вместо:
def create_user(name, email, age, is_admin=False):
...
Можно:
def create_user(**kwargs):
...
3. Расширение без поломки интерфейса
У тебя есть базовый метод:
def process(data, **kwargs):
...
➡️ В будущем можно спокойно добавить флаги, не меняя вызовы.
🗣️ Запомни: *args и **kwargs — это про гибкость и масштабируемость. Главное — использовать их осознанно: когда действительно нужно, а не “на всякий случай”.
📍Где применяется:
Декораторы, middleware, логгеры, фреймворки (Django, Flask), адаптеры, кастомные API, генераторы CLI-интерфейсов.