Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the value of dataclass field in __post_init__ when frozen=True?

Tags:

python

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' 
like image 585
nicholishen Avatar asked Dec 13 '18 07:12

nicholishen


People also ask

What is __ Post_init __?

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.

How do you create a Dataclass 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.

Can Python Dataclass have methods?

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.

What is DataClasses?

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.


1 Answers

Use the same thing the generated __init__ method does: object.__setattr__.

def __post_init__(self):     object.__setattr__(self, 'value', RANKS.index(self.rank) + 1) 
like image 86
user2357112 supports Monica Avatar answered Nov 07 '22 19:11

user2357112 supports Monica