Можно ли список сделать значением по умолчание в функции?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Можно ли список сделать значением по умолчанию в функции?
Технически можно, но это антипаттерн, который приводит к неожиданным ошибкам. Объясню почему и как правильно.
Проблема с изменяемыми значениями по умолчанию
Дефолтные значения вычисляются один раз при определении функции, а не при каждом вызове. Если это изменяемый объект (список, словарь), он становится общим для всех вызовов:
# ❌ НЕПРАВИЛЬНО
def add_item(item, lst=[]):
lst.append(item)
return lst
result1 = add_item(1) # [1]
result2 = add_item(2) # [1, 2] — список переиспользуется!
result3 = add_item(3, []) # [3]
В этом примере первые два вызова работают с одним и тем же списком, потому что дефолтный [] создаётся один раз при определении функции.
Правильный подход: None как дефолт
Используй None как дефолтное значение и инициализируй список внутри функции:
# ✅ ПРАВИЛЬНО
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
result1 = add_item(1) # [1]
result2 = add_item(2) # [2] — свежий список для каждого вызова
result3 = add_item(3, [100]) # [100, 3]
Более элегантный вариант с декоратором
from functools import wraps
def default_none_to_list(func):
@wraps(func)
def wrapper(*args, **kwargs):
if lst in kwargs and kwargs[lst] is None:
kwargs[lst] = []
return func(*args, **kwargs)
return wrapper
@default_none_to_list
def add_item(item, lst=None):
lst.append(item)
return lst
Почему это происходит?
Привязка дефолтных аргументов происходит в момент компиляции функции, а не во время её вызова. Это связано с тем, как Python работает с объектами и их жизненным циклом.
Вывод
Используй None как дефолтное значение для изменяемых типов данных (список, словарь, множество). Это принятая в сообществе практика и убережёт тебя от трудноуловимых ошибок.
Для неизменяемых типов (int, str, tuple) дефолтные значения безопасны:
# ✅ Безопасно
def greet(name="Alice", age=30):
return f"{name} is {age}"