
3 ошибки при работе с dataclasses в Python
badcasedaily1 1 час назад 3 ошибки при работе с dataclasses в Python Простой 5 мин 175 Блог компании OTUS Python * Программирование * Обзор Dataclasses появились в Python 3.7 и быстро стали стандартом: меньше...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. badcasedaily1 1 час назад 3 ошибки при работе с dataclasses в Python Простой 5 мин 175 Блог компании OTUS Python * Программирование * Обзор Dataclasses появились в Python 3. 7 и быстро стали стандартом: меньше бойлерплейта, чем у обычных классов, проще, чем attrs, и не требуют зависимостей. Выглядят настолько просто, что кажется, что ломаться там нечему.
Но у них есть три ловушки, которые не видны при написании. Ошибка 1: mutable default в поляхВот этот код:from dataclasses import dataclass @dataclass class UserConfig: name: str permissions: list = ... Python выдаёт ValueError: mutable default value и отказывается создавать класс.
Технические детали
Это хорошо: ошибка ловится сразу, разработчик идёт в документацию и узнаёт про field(default_factory=... Часто разработчик «исправляет» ошибку вот так:@dataclass class UserConfig: name: str permissions: list = None def __post_init__(self): if self. permissions is None: self.
permissions = Формально работает, но permissions теперь Optional], хотя по смыслу это всегда список. Mypy будет ругаться (или молчать с type: ignore), и каждое место использования будет либо проверять на None, либо игнорировать тип. Через полгода кто-то передаст None явно, думая, что это допустимо, и получит баг.
Правильный способ:from dataclasses import dataclass, field @dataclass class UserConfig: name: str permissions: list = field(default_factory=list)default_factory вызывается при каждом создании экземпляра. Каждый UserConfig получает свой пустой список. Тип всегда list, никакого Optional, mypy доволен.
Отраслевые последствия
Для более сложных значений по умолчанию — lambda:@dataclass class PipelineConfig: name: str steps: list = field(default_factory=lambda: ) metadata: dict = field(default_factory=dict)Каждый экземпляр получает свою копию steps и свой пустой dict. Мутация одного экземпляра не затрагивает другие. Но часто бывает так, что один экземпляр UserConfig мутировал shared-список permissions, и все остальные экземпляры (созданные до исправления, когда default был списком, а не factory) внезапно получали чужие permissions.
РОшибка 2: frozen=True не делает объект неизменяемымМногие разработчики думают, что frozen=True делает dataclass иммутабельным. @dataclass(frozen=True) class Report: title: str tags: list = field(default_factory=list) report = Report(title="Q1", tags=)frozen=True запрещает присваивание в поля. title = "Q2" вызовет FrozenInstanceError.
Но вот это работает без ошибок:report. append("urgent print(report. tags) # — объект изменился!
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





