Data Classes in Python | Set 2 (Decorator Parameters)

Prerequisite: Data Classes in Python | Set 1

In this post, we will discuss how to modify the default constructor which dataclass module virtually makes for us.

dataclass() decorator –

@dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

By changing the values of these parameters, we can modify the behavior and functioning of the default constructor been made for our DataClasses.

init: This parameter specifies that there should be a default constructor or not.

True (default): There will be a default Constructor.
False         : There won't be a default Constructor.
filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass
  
@dataclass(init = False)
class GfgArticle():
  
    title: str
    author: str
    language: str
    upvotes: int
  
# A DataClass object
article = GfgArticle("DataClasses",
                     "vibhu4agarwal",
                     "Python", 0)

chevron_right


TypeError: object() takes no parameters

repr : This parameter specifies how the __repr__() function will behave. False value corresponds to hash value representation of the object in memory. True value corresponds to DataClass representation of the object.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass
  
@dataclass(repr = False)
class GfgArticle():
  
    title: str
    author: str
    language: str
    upvotes: int
  
# A DataClass object
article = GfgArticle("DataClasses",
                     "vibhu4agarwal",
                     "Python", 0)
print(article)

chevron_right


Output:

__main__.GfgArticle object at 0x7f391b7ddbe0

eq : This parameter is used to specify the operation performed in comparison when two DataClasses are compared for equality using == or != operators. eq takes in boolean values.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass
  
@dataclass(repr = False, eq = False)
class GfgArticle():
  
    title: str
    author: str
    language: str
    upvotes: int
  
# Two DataClass objects
dClassArticle1 = GfgArticle("DataClasses",
                            "vibhu4agarwal",
                            "Python", 0)
  
dClassArticle2 = GfgArticle("DataClasses",
                            "vibhu4agarwal",
                            "Python", 0)
  
equal = dClassArticle1 == dClassArticle2
print('Classes Equal:', equal)

chevron_right


Output:

__main__.GfgArticle object at 0x7ff501c63c18
__main__.GfgArticle object at 0x7ff501c63ba8
Classes Equal: False

When eq=False, the two object are compared using their hash based on its location in memory like two normal objects. Since the two objects have different hash representation, their equality returns False.

order : Comparison between two DataClasses are not only restricted only to equality, but also supports >, >=, < and <= operators when order=True is set in argument parameter.
The comparison between objects is based on the comparison between their corresponding attributes, which is done one by one starting from the first one.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass 
    
@dataclass(order = True)
class A():
    var1: int
    var2: str
    var3: float
  
obj1 = A(1, "GeeksForGeeks", 7.0)
obj2 = A(2, "GeeksForGeeks", 7.0)
obj3 = A(1, "GfG", 7.0)
obj4 = A(1, "GeeksForGeeks", 8.0)
  
print(obj1 >  obj2)
print(obj1 <  obj3)
print(obj1 >= obj4)

chevron_right


Output:

False
True
False

frozen : This sets all the variables in the DataClass as one-time initializable that is once initialized, it cannot be reassigned a new value. C++ users can relate this to const and Java users can relate this to final keyword.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass 
    
@dataclass(frozen = True)
class GfgArticle():
    
    title: str
    author: str
    language: str
    upvotes: int
  
dClassArticle = GfgArticle("DataClasses",
                           "vibhu4agarwal",
                           "Python", 0)
print(dClassArticle)
  
dClassArticle.upvotes = 100
print(dClassArticle)

chevron_right


GfgArticle(title=’DataClasses’, author=’vibhu4agarwal’, language=’Python’, upvotes=0)
Traceback (most recent call last):
File “dClass.py”, line 16, in <module>
dClassArticle.upvotes = 100
File “<string>”, line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field ‘upvotes’

unsafe_hash : Generally, mutable objects in python are Unhashable. This means their hash cannot be generated using the hash() function of Python.
Since any class objects including DataClass objects’ values can change, they are mutable. Hence they shouldn’t be able to produce any hash value.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass 
    
@dataclass
class GfgArticle():
    
    title: str
    author: str
    language: str
    upvotes: int
  
dClassArticle = GfgArticle("DataClasses",
                           "vibhu4agarwal",
                           "Python", 0)
print(dClassArticle)
print(hash(dClassArticle))

chevron_right


GfgArticle(title=’DataClasses’, author=’vibhu4agarwal’, language=’Python’, upvotes=0)
Traceback (most recent call last):
File “dClass.py”, line 15, in <module>
print(hash(dClassArticle))
TypeError: unhashable type: ‘GfgArticle’

However frozen=True sets the variables one-time initializable and hence makes the object immutable. This safely generates a hash for the DataClass object.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass 
    
@dataclass(frozen = True)
class GfgArticle():
    
    title: str
    author: str
    language: str
    upvotes: int
  
dClassArticle = GfgArticle("DataClasses",
                           "vibhu4agarwal",
                           "Python", 0)
print(dClassArticle)
print(hash(dClassArticle))

chevron_right


Output:

GfgArticle(title=’DataClasses’, author=’vibhu4agarwal’, language=’Python’, upvotes=0)
9111021502060859577

unsafe_hash forces a DataClass which is still mutable to generate a hash.

This case comes into use when logically, we know that once initialized, we aren’t going to change the Dataclass attributes’ values. But it comes down to the question of Can they be changed? or in other words, Is the DataClass is not frozen or not? While using unsafe_hash, if the DataClass is not frozen, then DataClass generates an unsafe hash, assuming that the class is frozen and then the programmer has to further use this very carefully.

filter_none

edit
close

play_arrow

link
brightness_4
code

from dataclasses import dataclass 
    
@dataclass(unsafe_hash = True)
class GfgArticle():
    
    title: str
    author: str
    language: str
    upvotes: int
  
dClassArticle = GfgArticle("DataClasses",
                           "vibhu4agarwal",
                           "Python", 0)
print(dClassArticle)
print(hash(dClassArticle))

chevron_right


Output:

GfgArticle(title=’DataClasses’, author=’vibhu4agarwal’, language=’Python’, upvotes=0)
8924105619418522237



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.