Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Операторы * и ** в Python: полный разбор
Это один из самых важных и многофункциональных операторов в Python. Расскажу обо всех применениях.
1. Распаковка итерируемых объектов (*)
В функциях:
def greet(a, b, c):
print(f"{a}, {b}, {c}")
args = ['Alice', 'Bob', 'Charlie']
greet(*args) # Распаковать список как отдельные аргументы
# Результат: Alice, Bob, Charlie
В списках и кортежах:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = [*list1, *list2]
print(combined) # [1, 2, 3, 4, 5, 6]
# Распаковка в разных местах
first, *middle, last = [1, 2, 3, 4, 5]
print(middle) # [2, 3, 4]
2. Распаковка словарей ()**
В функциях:
def print_person(name, age, city):
print(f"{name}, {age} лет, из {city}")
kwargs = {'name': 'Алиса', 'age': 30, 'city': 'Москва'}
print_person(**kwargs)
# Результат: Алиса, 30 лет, из Москва
В словарях:
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = {**dict1, **dict2}
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Переопределение значений
config_default = {'debug': False, 'port': 8000}
config_custom = {'debug': True}
config = {**config_default, **config_custom}
print(config) # {'debug': True, 'port': 8000}
3. *Сбор аргументов в функциях (args)
def sum_all(*numbers):
"""Сложить произвольное количество чисел"""
return sum(numbers)
print(sum_all(1, 2, 3, 4, 5)) # 15
print(sum_all(10, 20)) # 30
# args — это кортеж
def print_args(*args):
print(f"Тип: {type(args)}")
print(f"Значение: {args}")
print_args('a', 'b', 'c')
# Тип: <class 'tuple'>
# Значение: ('a', 'b', 'c')
4. **Сбор именованных аргументов (kwargs)
def build_profile(name, age, **kwargs):
"""Построить профиль с дополнительными полями"""
profile = {'name': name, 'age': age}
profile.update(kwargs) # Добавить все остальные ключ-значение
return profile
result = build_profile(
'Алиса',
30,
city='Москва',
job='Engineer',
hobbies=['reading', 'coding']
)
print(result)
# {'name': 'Алиса', 'age': 30, 'city': 'Москва', 'job': 'Engineer', 'hobbies': [...]}
5. **Комбинация *args и kwargs
def flexible_function(a, b, *args, **kwargs):
print(f"Позиционные: a={a}, b={b}")
print(f"*args: {args}")
print(f"**kwargs: {kwargs}")
flexible_function(1, 2, 3, 4, 5, name='Alice', city='NYC')
# Позиционные: a=1, b=2
# *args: (3, 4, 5)
# **kwargs: {'name': 'Alice', 'city': 'NYC'}
Важно: порядок параметров
# ✅ Правильно
def good(a, b, *args, c=None, **kwargs):
pass
# ❌ Неправильно
def bad(*args, c=None, b, **kwargs):
pass # SyntaxError
6. Распаковка в операции присваивания
# Базовое распаковывание
a, b, c = [1, 2, 3]
# С игнорированием значений
first, _, third = [1, 2, 3]
print(first, third) # 1, 3
# Распаковка нескольких
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last) # 1, [2, 3, 4], 5
# Обмен значений
a, b = 1, 2
a, b = b, a # Без временной переменной!
print(a, b) # 2, 1
7. Распаковка в декораторах
def log_calls(func):
def wrapper(*args, **kwargs):
print(f"Вызов: {func.__name__}({args}, {kwargs})")
result = func(*args, **kwargs)
print(f"Результат: {result}")
return result
return wrapper
@log_calls
def add(a, b):
return a + b
add(5, 10)
# Вызов: add((5, 10), {})
# Результат: 15
8. Распаковка в интроспекции и рефлексии
import inspect
def example(a, b, *args, c=None, **kwargs):
pass
sig = inspect.signature(example)
print(sig) # (a, b, *args, c=None, **kwargs)
# Получить параметры
for param_name, param in sig.parameters.items():
print(f"{param_name}: {param.kind}")
9. Распаковка в функциях высшего порядка
# Partial application через распаковку
def multiply(a, b):
return a * b
numbers = [3, 4]
result = multiply(*numbers)
print(result) # 12
# Применение функции с разными наборами аргументов
funcs_and_args = [
(sum, [1, 2, 3]),
(max, [10, 20, 30]),
(min, [5, 3, 8])
]
results = [func(*args) for func, args in funcs_and_args]
print(results) # [6, 30, 3]
10. Тонкости и частые ошибки
# ❌ Ошибка: *args должен быть перед **kwargs
def wrong(*kwargs, **args): # SyntaxError
pass
# ❌ Ошибка: нельзя использовать * дважды
result = [*list1, *list2, *list3] # OK в списках
# ✅ Но работает, если список — элемент tuple
def func(*args):
return args
result = func(*[1, 2, 3], *[4, 5]) # OK: (1, 2, 3, 4, 5)
# Распаковка в именованных аргументах: ключи должны совпадать
def greet(name, greeting):
return f"{greeting}, {name}!"
kwargs = {'greeting': 'Hello', 'name': 'Alice'}
print(greet(**kwargs)) # Hello, Alice!
# ❌ KeyError: лишний ключ в kwargs
kwargs = {'name': 'Alice', 'age': 30}
greet(**kwargs) # TypeError: got an unexpected keyword argument 'age'
Практический пример: гибкий API
class APIClient:
def __init__(self, base_url, **config):
self.base_url = base_url
self.timeout = config.get('timeout', 30)
self.retries = config.get('retries', 3)
self.headers = config.get('headers', {})
def request(self, method, endpoint, *args, **kwargs):
"""Гибкий метод для любых запросов"""
url = f"{self.base_url}{endpoint}"
# args для позиционных параметров (редко)
# kwargs для параметров запроса
params = kwargs.pop('params', {})
headers = {**self.headers, **kwargs.pop('headers', {})}
return self._make_request(
method,
url,
params=params,
headers=headers,
**kwargs # Остальные параметры (data, json, etc)
)
# Использование
client = APIClient(
'https://api.example.com',
timeout=60,
headers={'Authorization': 'Bearer token'}
)
data = client.request(
'POST',
'/users',
json={'name': 'Alice'},
headers={'X-Request-ID': '123'}
)
Итоги
*распаковывает итерируемые (списки, кортежи) в позиционные аргументы**распаковывает словари в именованные аргументы (ключ=значение)*argsсобирает переменное количество позиционных аргументов в кортеж**kwargsсобирает переменное количество именованных аргументов в словарь- Порядок: обычные параметры → *args → именованные с дефолтами → **kwargs
- Распаковка работает везде: в функциях, списках, словарях, присваивании
Эти операторы — ключ к написанию гибких, масштабируемых Python функций и хорошему пониманию того, как работают встроенные функции типа print(), zip(), map().