Python

Python kwargs: пример именованных аргументов

**kwargs в Python собирает именованные аргументы функции в словарь. Это удобно, когда функция принимает гибкий набор настроек: timeout=30, debug=True, retries=3

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

Базовый пример

def show_settings(**kwargs):
    print(kwargs)

show_settings(theme='dark', limit=20)

Результат:

{'theme': 'dark', 'limit': 20}

Внутри функции kwargs — обычный словарь. С ним можно работать через .items(), .get(), проверку ключей и другие методы словаря

def show_settings(**kwargs):
    for name, value in kwargs.items():
        print(name, value)

show_settings(theme='dark', limit=20)

Значения по умолчанию через get

Часто **kwargs используют для необязательных настроек

def make_request(endpoint, **options):
    timeout = options.get('timeout', 10)
    retries = options.get('retries', 1)
    debug = options.get('debug', False)

    print(endpoint)
    print(timeout, retries, debug)

make_request('/users', timeout=30, debug=True)

Если ключ не передан, .get() вернет значение по умолчанию. В примере retries станет равен 1

Такой прием хорошо подходит для маленьких helper-функций, но не заменяет документацию. Пользователь функции должен понимать, какие ключи поддерживаются

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

По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы

Распаковка словаря через **

** можно использовать не только в определении функции, но и при вызове

def create_user(name, role, active=True):
    print(name, role, active)

data = {
    'name': 'Анна',
    'role': 'admin',
    'active': False,
}

create_user(**data)

Python распакует словарь в именованные аргументы. Это удобно, когда данные пришли из JSON, формы или конфига

Ключи словаря должны совпадать с именами параметров функции. Если в словаре будет лишний ключ, Python покажет ошибку

Проверка разрешенных ключей

Если функция принимает **kwargs, полезно проверять неизвестные настройки

def make_request(endpoint, **options):
    allowed = {'timeout', 'retries', 'debug'}
    unknown = set(options) - allowed

    if unknown:
        raise ValueError(f'Неизвестные настройки: {unknown}')

    timeout = options.get('timeout', 10)
    retries = options.get('retries', 1)
    debug = options.get('debug', False)

    print(endpoint, timeout, retries, debug)

make_request('/users', timeout=30)

Без такой проверки опечатка может пройти незаметно

make_request('/users', timout=30)

Если не проверять ключи, функция просто не увидит timeout и возьмет значение по умолчанию

kwargs и обычные параметры

Можно сочетать обычные аргументы и **kwargs

def send_message(to, text, **options):
    priority = options.get('priority', 'normal')
    silent = options.get('silent', False)

    print(to, text, priority, silent)

send_message('user@example.com', 'Привет', priority='high')

Обычные аргументы описывают обязательную часть функции. **kwargs оставляет место для дополнительных настроек

Если параметр важный и используется всегда, не прячьте его в kwargs

def send_message(to, text, priority='normal'):
    .

Так функция читается лучше

kwargs и args

*args собирает позиционные аргументы в кортеж

def show_args(*args):
    print(args)

show_args(1, 2, 3)

**kwargs собирает именованные аргументы в словарь

def show_kwargs(**kwargs):
    print(kwargs)

show_kwargs(theme='dark', limit=20)

Их можно использовать вместе, но порядок важен

def example(required, *args, **kwargs):
    print(required)
    print(args)
    print(kwargs)

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

Передать kwargs дальше

Иногда функция-обертка принимает настройки и передает их другой функции

def connect(host, port=5432, timeout=10):
    print(host, port, timeout)

def connect_with_defaults(host, **kwargs):
    kwargs.setdefault('timeout', 30)
    return connect(host, **kwargs)

connect_with_defaults('localhost', port=5433)

Здесь connect_with_defaults() добавляет значение по умолчанию и передает остальные именованные аргументы в connect()

Такой прием часто используют в обертках над библиотеками. Главное — не передавать любые настройки вслепую, если внутренняя функция принимает ограниченный набор параметров

kwargs в форматировании

**kwargs удобно использовать для шаблонов

def render_message(template, **context):
    return template.format(**context)

message = render_message(
    'Привет, {name}. У вас {count} задач',
    name='Анна',
    count=3,
)

print(message)

Результат:

Привет, Анна. У вас 3 задач

Если в шаблоне есть поле, которого нет в context, Python покажет KeyError. Это полезно: ошибка сразу подсказывает, какого значения не хватает

Частые ошибки

Использовать kwargs, когда параметры известны заранее

Не документировать поддерживаемые ключи

Не проверять опечатки в именах ключей

Путать args и *kwargs

Думать, что имя kwargs обязательно. На самом деле важны две звездочки, но имя kwargs стало общепринятым

Практические задачи

Напишите функцию show_settings(**kwargs) и выведите все ключи

Добавьте значения по умолчанию через .get()

Передайте словарь в функцию через **data

Сделайте проверку неизвестных ключей

Сравните функцию с явными параметрами и функцию с **kwargs

**kwargs собирает именованные аргументы в словарь и помогает делать гибкие функции с дополнительными настройками. Он полезен для helper-функций, оберток и передачи параметров дальше

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

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x