Переменное количество аргументов: *args и **kwargs

Переменное количество аргументов: *args и **kwargs Функции

Привет! Иногда нам нужно создать функцию, которая может принимать любое количество аргументов. Например, функция print() может принимать сколько угодно значений. В Python для этого существуют *args и **kwargs.

В этой статье мы разберём:

  • Что такое *args
  • Что такое **kwargs
  • Как их использовать
  • Практические примеры

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Python
  • Базовое понимание функций и аргументов

Совет: *args и **kwargs — это одна из самых мощных фишек Python. Они делают функции гибкими.

Основная часть

Что такое *args

*args (arguments) — это способ передать в функцию произвольное количество позиционных аргументов. Все аргументы собираются в кортеж.

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3))        # 6
print(sum_all(10, 20, 30, 40)) # 100
print(sum_all())               # 0 (без аргументов)

Совет: Имя args не обязательно. Можно использовать любое имя со звёздочкой: *numbers*items. Но args — это соглашение.

*args в сочетании с обычными параметрами

def greet(greeting, *names):
    for name in names:
        print(f"{greeting}, {name}!")

greet("Привет", "Анна", "Иван", "Петр")
# Привет, Анна!
# Привет, Иван!
# Привет, Петр!

Важно: *args собирает все оставшиеся позиционные аргументы.

Что такое **kwargs

**kwargs (keyword arguments) — это способ передать произвольное количество именованных аргументов. Все аргументы собираются в словарь.

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Анна", age=25, city="Москва")
# name: Анна
# age: 25
# city: Москва

Совет: Имя kwargs не обязательно. Можно использовать любое имя с двумя звёздочками: **data**options. Но kwargs — это соглашение.

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

def create_user(name, **kwargs):
    user = {'name': name}
    user.update(kwargs)
    return user

print(create_user("Анна", age=25, city="Москва"))
# {'name': 'Анна', 'age': 25, 'city': 'Москва'}

print(create_user("Иван", city="Казань", phone="+7-123-456-78-90"))
# {'name': 'Иван', 'city': 'Казань', 'phone': '+7-123-456-78-90'}

Использование *args и **kwargs вместе

def func(a, b, *args, **kwargs):
    print(f"a: {a}")
    print(f"b: {b}")
    print(f"args: {args}")
    print(f"kwargs: {kwargs}")

func(1, 2, 3, 4, 5, x=10, y=20)
# a: 1
# b: 2
# args: (3, 4, 5)
# kwargs: {'x': 10, 'y': 20}

Важно: Порядок: обычные параметры → *args → **kwargs.

Распаковка списков и словарей

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

# Распаковка списка
numbers = [1, 2, 3]
print(*numbers)   # 1 2 3

def add(a, b, c):
    return a + b + c

print(add(*numbers))   # 6

# Распаковка словаря
user = {'name': 'Анна', 'age': 25}
def greet(name, age):
    print(f"Привет, {name}! Тебе {age} лет.")

greet(**user)   # Привет, Анна! Тебе 25 лет.

Примеры из реальной жизни

Пример 1. Логирование:

def log(level, message, **kwargs):
    print(f"[{level}] {message}")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

log("INFO", "Пользователь вошёл", user="Анна", ip="192.168.1.1")
# [INFO] Пользователь вошёл
#   user: Анна
#   ip: 192.168.1.1

Пример 2. Декоратор с аргументами:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def say_hello(name):
    print(f"Привет, {name}!")

say_hello("Анна")
# Привет, Анна!
# Привет, Анна!
# Привет, Анна!

Пример 3. Обёртка с логированием:

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Вызов {func.__name__}")
        print(f"Аргументы: {args}, {kwargs}")
        result = func(*args, **kwargs)
        print(f"Результат: {result}")
        return result
    return wrapper

@logger
def add(a, b):
    return a + b

add(3, 5)
# Вызов add
# Аргументы: (3, 5), {}
# Результат: 8

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

# Ошибка: неправильный порядок
def func(**kwargs, *args):   # Неправильно!
    pass

# Правильно
def func(*args, **kwargs):
    pass

Задачи для закрепления

Задача 1. Напиши функцию sum_all(*args), которая суммирует любое количество чисел.

Задача 2. Напиши функцию print_user_info(**kwargs), которая выводит информацию о пользователе.

Задача 3. Напиши функцию create_profile(name, **kwargs), которая создаёт словарь с данными пользователя.

Задача 4. Напиши функцию log_message(level, message, **kwargs).

Задача 5. В каком порядке должны идти *args и **kwargs?

Ответы:

Задача 1.

def sum_all(*args):
    return sum(args)

Задача 2.

def print_user_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

Задача 3.

def create_profile(name, **kwargs):
    profile = {'name': name}
    profile.update(kwargs)
    return profile

Задача 4.

def log_message(level, message, **kwargs):
    print(f"[{level}] {message}")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

Задача 5.

# Сначала *args, потом **kwargs

Нюансы и подводные камни

  • Имена args и kwargs — это соглашение, а не синтаксис. Можно использовать *items и **options.
  • *args собирает позиционные аргументы в кортеж.
  • **kwargs собирает именованные аргументы в словарь.
  • Порядок параметров в функции: обычные → *args → именованные → **kwargs.
  • *args и **kwargs можно использовать не только в определении, но и при вызове функции (распаковка).
  • При использовании *args в сочетании с обычными параметрами, *args собирает все оставшиеся позиционные аргументы.
  • **kwargs не гарантирует порядок, так как словари неупорядочены (до Python 3.7 порядок сохранялся, но полагаться на него не стоит).

Частые ошибки и как их избежать

Ошибка 1: Неправильный порядок параметров

Неправильно:

def func(**kwargs, *args):   # SyntaxError
    pass

Правильно:

def func(*args, **kwargs):
    pass

Ошибка 2: Путаница между *args и **kwargs при вызове

Неправильно:

def func(a, b, c):
    pass

args = [1, 2, 3]
func(args)   # Ошибка! Передаётся один список

Правильно:

func(*args)   # Распаковка списка

Ошибка 3: Использование **kwargs для позиционных аргументов

**kwargs — только для именованных аргументов.

Шпаргалка

Что нужноКак пишется
Произвольное число позиционных аргументов*args
Произвольное число именованных аргументов**kwargs
Распаковка списка*list
Распаковка словаря**dict
Порядок параметровdef func(a, b, *args, **kwargs)

Заключение

Сегодня мы:

  • Узнали, что такое *args и **kwargs
  • Научились создавать гибкие функции
  • Разобрали практические примеры
  • Рассмотрели частые ошибки

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×