Сделать Dataclass объект immutable после __post_init__
Есть класс
from typing import List
from dataclasses import dataclass, field
@dataclass(repr=False, eq=False, order=False)
class Models:
path: str
targets: List[str] = field(default_factory=list)
columns: List[str] = field(default_factory=list, init=False)
Атрибут columns я определяю в __ post_init __(self)
def __post_init__(self):
self.columns = ['a', 'b', 'c']
И мне бы хотелось сделать объект класса Models immutable после инициализации (пост-инициализации?)
Если прописать @dataclass(Frozen=True) , то теряется возможность определить атрибут в post_init
Можно ли прописать аналог Frozen=True, только уже после init и post_init?
Какие могут быть альтернативные варианты?
Ответы (1 шт):
Автор решения: gil9red
→ Ссылка
Можно переопределить магический метод __setattr__ и в нем выбрасывать исключение.
Пример:
from typing import List
from dataclasses import dataclass, field
@dataclass(repr=False, eq=False, order=False)
class Models:
path: str
targets: List[str] = field(default_factory=list)
columns: List[str] = field(default_factory=list, init=False)
def __post_init__(self):
self.columns = ['a', 'b', 'c']
self._is_post_init = True
def __setattr__(self, key, value):
if hasattr(self, '_is_post_init'):
raise Exception(f'cannot assign to field "{key}"')
return super().__setattr__(key, value)
Models('123').columns = []
# Exception: cannot assign to field "columns"