Приведён фрагмент Python: def add(item, lst=[]): lst.append(item); return lst. Объясните проблему этого кода, последствия в долгоживущих серверах и предложите безопасные альтернативы

11 Дек 2025 в 08:01
15 +1
0
Ответы
1
Проблема
- В определении функции значение по умолчанию вычисляется один раз при загрузке модуля, поэтому мутабельный объект используется повторно для всех вызовов. В вашем фрагменте это lst=[]\text{lst}=[]lst=[].
- Следствие: данные накапливаются между вызовами, то есть вызовы не изолированы друг от друга.
Краткий пример поведения
- Первый вызов: add(1)→[1]\text{add(1)}\to [1]add(1)[1]
- Второй вызов: add(2)→[1,2]\text{add(2)}\to [1,2]add(2)[1,2] — вместо ожидаемого [2][2][2].
Последствия на долгоживущих серверах
- Накопление памяти (памятный «утечка»), если список постоянно растёт.
- Пересечение данных между разными запросами/сессиями — риск утечки данных и некорректного поведения.
- В многопоточной среде — состояние разделяется между потоками, возможны гонки и неконсистентность без явной синхронизации.
- Потенциальные проблемы безопасности и сложность отладки из-за неявного состояния.
Безопасные альтернативы
1) Использовать sentinel `None` и создавать новый список внутри:
def add(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
2) Возвращать новый список (функция без сайд-эффектов):
def add(item, lst=None):
base = lst if lst is not None else []
return base + [item]
3) Если функция должна принимать уже существующий список, копировать вход (чтобы не менять внешнюю структуру):
def add(item, lst=None):
if lst is None:
lst = []
else:
lst = list(lst) # shallow copy
lst.append(item)
return lst
4) Если нужен общий (разделяемый) стейт — делать это явно: хранить в объекте/атрибуте, в базе данных или в кэше и защищать доступ (locks, очереди, процессы, атомарные операции), не в дефолтном аргументе.
Рекомендация
- Для большинства случаев — вариант (1) с lst=None\text{lst}=\text{None}lst=None и явным созданием списка внутри функции — самый простой и безопасный.
11 Дек 2025 в 08:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир