В Python значения аргументов по умолчанию вычисляются один раз — при определении функции, а не при каждом вызове. Если использовать изменяемый объект (например, список) как аргумент по умолчанию, все вызовы функции без передачи значения будут работать с одним и тем же объектом.
В этом примере список 𝚡 создаётся при определении 𝚏𝚞𝚗, и каждый вызов 𝚏𝚞𝚗() добавляет в него единицу. Поэтому после первого вызова выводится [𝟷], а после второго уже [𝟷, 𝟷]. Такой эффект ловит многих: кажется, будто 𝚡 — новый пустой список при каждом вызове, но на деле это один и тот же, постоянно растущий список.
Чтобы избежать такого поведения, используйте 𝙽𝚘𝚗𝚎 как значение по умолчанию — тогда новый список создаётся при каждом вызове:
𝚍𝚎𝚏 𝚏𝚞𝚗(𝚡=𝙽𝚘𝚗𝚎):
𝚒𝚏 𝚡 𝚒𝚜 𝙽𝚘𝚗𝚎:
𝚡 = [ ]
𝚡.𝚊𝚙𝚙𝚎𝚗𝚍(𝟷)
𝚛𝚎𝚝𝚞𝚛𝚗 𝚡
Теперь каждый раз будет новый список: [𝟷] — поведение ожидаемое и безопасное для задач, где нужны независимые коллекции.
Эта особенность касается любых изменяемых типов: списков, словарей и даже пользовательских объектов. Полезно обратить на это внимание при проектировании функций‑инструментов и обработчиков.
Post #4446
757
- ✍ 4
- ❤ 3