How to freeze individual field of non-frozen dataclass?

Viewed 965

Is it possible to specify that a single field is frozen in a non-frozen dataclass? Something like this:

@dataclass
class Data:
    fixed: int = field(frozen=True)
    mutable: int = field(frozen=False)

d = Data(2, 3)
d.mutable = 5   # fine
d.fixed = 7     # raises exception

I realize this can be done manually with properties and setters accessing a private data field, but then we lose some of the advantages of dataclasses: for one, the private data field needs a different name, which means the auto-generated constructor annoyingly has different parameter names than the fields.

1 Answers

I came here looking for the same but, like @wim said in comments, dataclass does not support this, but using attrs it is possible:

from attrs import define, field
from attrs.setters import frozen

@define
class Data:
    fixed: int = field(on_setattr=frozen)
    mutable: int

d = Data(2, 3)
d.mutable = 5   # fine
d.fixed = 7     # raises exception
Related