Разберите следующий фрагмент на Python: "def append_item(x, lst=[]): lst.append(x); return lst" — почему поведение функции может быть неожиданным при нескольких вызовах, как это исправить и какие ещё тонкости с изменяемыми аргументами существуют

30 Апр в 10:46
16 +1
0
Ответы
1
Коротко и по делу.
Почему поведение неожиданное
- В Python значение аргумента по умолчанию вычисляется один раз при определении функции, а не при каждом вызове. Для функции
def append_item(x, lst=[]):
lst.append(x)
return lst
один и тот же список `lst` используется при всех вызывах. Пример:
- append_item(1) возвращает [1][1][1] - append_item(2) возвращает [1,2][1, 2][1,2] — т.е. элементы накапливаются в одном и том же списке.
Как исправить
- Использовать "sentinel" `None` и создавать новый список внутри функции:
def append_item(x, lst=None):
if lst is None:
lst = []
lst.append(x)
return lst
Теперь:
- append_item(1) → [1][1][1] - append_item(2) → [2][2][2]
Другие тонкости с изменяемыми аргументами
- По умолчанию безопасны неизменяемые типы (числа, строки, кортежи). Изменяемые (list, dict, set, пользовательские объекты) могут вести себя как общий состояние между вызовами.
- Если функция должна не менять переданный аргумент, а вернуть новую коллекцию, копируйте: `lst = lst.copy()` или `new = list(old)`. Для вложенных структур — `copy.deepcopy`.
- В классах и dataclass лучше использовать `default_factory` для полей-коллекций:
from dataclasses import dataclass, field
@dataclass
class C:
items: list = field(default_factory=list)
- Замечание о замыкании: mutable в замыкании тоже хранится один объект; иногда используют аргумент по умолчанию, чтобы зафиксировать текущее значение.
- Потокобезопасность: общий изменяемый объект между вызовами может привести к гонкам в многопоточной среде.
- Шалловая копия vs глубокая: `copy()` не защищает от изменений вложенных изменяемых элементов.
Резюме: не используйте изменяемые объекты как значения по умолчанию; применяйте `None` + создание нового объекта или специальные механизмы (default_factory, копирование) в зависимости от задачи.
30 Апр в 10:52
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир