Sunday, December 29, 2024
Google search engine
HomeLanguagesData Classes in Python | Set 2 (Decorator Parameters)

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.




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)


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.




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)


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.




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)


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.




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)


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.




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)


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.




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))


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.




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))


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.




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))


Output:

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

RELATED ARTICLES

Most Popular

Recent Comments