Как использовать @dataclass с default_factory?
Использование модуля dataclasses в Python существенно упрощает создание классов, предназначенных для хранения данных, благодаря автоматической генерации служебных методов вроде init и repr. Однако при проектировании структуры таких классов необходимо проявлять осторожность с изменяемыми типами данных, такими как списки, словари или множества.
Одной из классических ошибок начинающих разработчиков является попытка указать изменяемый объект в качестве значения по умолчанию напрямую, например через атрибут со значением в виде пустого списка. В языке Python аргументы по умолчанию и значения по умолчанию в датаклассах вычисляются один раз в момент определения класса, а не в момент создания каждого нового экземпляра.
Это приводит к тому, что один и тот же объект списка будет разделен между всеми созданными экземплярами датакласса, создавая скрытые и трудноуловимые баги, когда изменение данных в одном объекте неожиданно затрагивает все остальные. Чтобы избежать подобного поведения, стандартный модуль предоставляет специальную функцию field с параметром default_factory.
Функция default_factory принимает вызываемый объект, например list, dict или set, и вызывает его для каждого нового экземпляра датакласса, гарантируя создание уникального изолированного контейнера для каждого объекта. Аналогичный подход следует применять и для других изменяемых структур данных, обеспечивая корректность и предсказуемость работы вашей программы.