I'm trying to create a frozen dataclass but I'm having issues with setting a value from __post_init__
. Is there a way to set a field value based on values from an init param
in a dataclass
when using the frozen=True
setting?
RANKS = '2,3,4,5,6,7,8,9,10,J,Q,K,A'.split(',') SUITS = 'H,D,C,S'.split(',') @dataclass(order=True, frozen=True) class Card: rank: str = field(compare=False) suit: str = field(compare=False) value: int = field(init=False) def __post_init__(self): self.value = RANKS.index(self.rank) + 1 def __add__(self, other): if isinstance(other, Card): return self.value + other.value return self.value + other def __str__(self): return f'{self.rank} of {self.suit}'
and this is the trace
File "C:/Users/user/.PyCharm2018.3/config/scratches/scratch_5.py", line 17, in __post_init__ self.value = RANKS.index(self.rank) + 1 File "<string>", line 3, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'value'
The post-init function is an in-built function in python and helps us to initialize a variable outside the __init__ function. post-init function in python.
Use the @dataclass decorator from the dataclasses module to make a class a dataclass. The dataclass object implements the __eq__ and __str__ by default. Use the astuple() and asdict() functions to convert an object of a dataclass to a tuple and dictionary. Use frozen=True to define a class whose objects are immutable.
A dataclass can very well have regular instance and class methods. Dataclasses were introduced from Python version 3.7. For Python versions below 3.7, it has to be installed as a library.
dataclass module is introduced in Python 3.7 as a utility tool to make structured classes specially for storing data. These classes hold certain properties and functions to deal specifically with the data and its representation. DataClasses in widely used Python3.6. Although the module was introduced in Python3.
Use the same thing the generated __init__
method does: object.__setattr__
.
def __post_init__(self): object.__setattr__(self, 'value', RANKS.index(self.rank) + 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With