Understanding Python Dataclasses

06 Aug, 2021
DataClasses has been added in a recent addition in python 3.7 as a utility tool for storing data. DataClasses provides a decorator and functions for automatically adding generated special methods such as __init__() , __repr__() and __eq__() to user-defined classes.
DataClasses are like normal classes in Python, but they have some basic functions like instantiation, comparing, and printing the classes already implemented.
Installing the DataClasses module:
pip install dataclasses
The syntax of the dataclass is:
Syntax: @dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
Parameters:
init: If true  __init__() method will be generated
repr: If true  __repr__() method will be generated
eq: If true  __eq__() method will be generated
order: If true  __lt__(), __le__(), __gt__(), and __ge__() methods will be generated.
unsafe_hash: If False __hash__() method is generated according to how eq and frozen are set
frozen: If true assigning to fields will generate an exception.
DataClass module provides a handy way to make classes less wordy. Let us see the traditional approach without using DataClass.
Python3
# creating a employee classclass employee:         # init method or constructor    def __init__(self, name, emp_id, age, city):                 # Instance Variable        self.name = name        self.emp_id = emp_id        self.age = age        self.city = city         # magic function to return class object    def __repr__(self):        return ("employee (name={}, emp_id={}, age={}, city={} )"                .format(self.name, self.emp_id, self.age, self.city))         # magic function to return boolean    def __eq__(self, check):        return ((self.name, self.emp_id, self.age, self.city) ==                ((check.name, check.emp_id, check.age, check.city)))  # initialization the objectemp1 = employee("Satyam", "ksatyam858", 21, 'Patna')emp2 = employee("Anurag", "au23", 28, 'Delhi')emp3 = employee("Satyam", "ksatyam858", 21, 'Patna') print("employee object are :")print(emp1)print(emp2)print(emp3) # printing new lineprint() # referring two object to check equalityprint("Data in emp1 and emp2 are same? ", emp1 == emp2)print("Data in emp1 and emp3 are same? ", emp1 == emp3)
employee object are :
employee (name=Satyam, emp_id=ksatyam858, age=21, city=Patna )
employee (name=Anurag, emp_id=au23, age=28, city=Delhi )
employee (name=Satyam, emp_id=ksatyam858, age=21, city=Patna )

Data in emp1 and emp2 are same?  False
Data in emp1 and emp3 are same?  True
In the above code the biggest problem in passing the argument in __init__, __repr__, and __eq__. Each time it has to copy its properties and return the object. It is a good way of dealing with a small amount of data but supposes we have work with large data. It makes your code more complicated. So, that why DataClass will implement to make your code easier and handy.
Here are the same example, implemented in Python DataClasses. 
Python3
# A basic Data Class# importing dataclass modulefrom dataclasses import dataclass # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    emp_id: str    age: int    city: str  emp1 = employee("Satyam", "ksatyam858", 21, 'Patna')emp2 = employee("Anurag", "au23", 28, 'Delhi')emp3 = employee("Satyam", "ksatyam858", 21, 'Patna') print("employee object are :")print(emp1)print(emp2)print(emp3) # printing new lineprint() # referring two object to check equalityprint("Data in emp1 and emp2 are same? ", emp1 == emp2)print("Data in emp1 and emp3 are same? ", emp1 == emp3)
Output: 
employee object are : employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’Patna’) employee(name=’Anurag’, emp_id=’au23′, age=28, city=’Delhi’) employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’Patna’)Data in emp1 and emp2 are same?  False Data in emp1 and emp3 are same?  True  
In the above code, we don’t need to write a code for __init__, __repr__, and __eq__ function. 
The field() objects describe each defined field.  
Syntax: dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None)
Parameters:
default
default_factory
init
repr
hash
compare
metadata
Example: Demonstration of how to view the fields of a dataclass object. 
Python3
from dataclasses import dataclass # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    emp_id: str    age: int    city: str  # object of the classemp = employee("Satyam", "ksatyam858", 21, 'Patna') emp.__dataclass_fields__
Output:
Explanation of the parameters :
default: This field is used to specify default values for this field.
Python3
# default field examplefrom dataclasses import dataclass, field  # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    emp_id: str    age: int           # default field set    # city : str = "patna"    city: str = field(default="patna")  emp = employee("Satyam", "ksatyam858", 21)print(emp)
Output:
employee(name=’Satyam’, emp_id=’ksatyam858′, age=21, city=’patna’)  
default_factory: This field accepts a function and returns the initial value of the field, it must be a zero-argument.
Python3
# default factory examplefrom dataclasses import dataclass, field  def get_emp_id():    id = 2345    return id # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    age: int           # default factory field    emp_id: str = field(default_factory=get_emp_id)    city: str = field(default="patna")  # object of dataclassemp = employee("Satyam", 21)print(emp)
Output:
employee(name=’Satyam’, age=21, emp_id=2345, city=’patna’)  
init : If true this field is included as a parameter to the generated __init__() method.
Python3
# init field examplefrom dataclasses import dataclass, field # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    age: int           # init field    emp_id: str    city: str = field(init=False, default="patna")  # object of dataclassemp = employee("Satyam", "ksatyam858", 21)print(emp)
Output:
employee(name=’Satyam’, age=’ksatyam858′, emp_id=21, city=’patna’)  
repr: If true (the default), this field is included in the string returned by the generated __repr__() method.
Python3
# repr fieldfrom dataclasses import dataclass, field # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    age: int    emp_id: str    city: str = field(init=False, default="patna", repr=True) emp = employee("Satyam", 21, "ksatyam858"),print(emp)
Output: 
employee(name=’Satyam’, age=21, emp_id=’ksatyam858′, city=’patna’)  
If repr is false then: 
Python3
city: str = field(init=False, default="patna", repr=False) emp = employee("Satyam", 21, "ksatyam858"),emp
Output:
employee(name='Satyam', age=21, emp_id='ksatyam858')
hash: If true, this field is included in the generated __hash__() method.
Python3
# hashfrom dataclasses import dataclass, field # A class for holding an employees content@dataclass(unsafe_hash=True)class employee:     # Attributes Declaration    # using Type Hints    name: str    age: int    emp_id: str = field(default_factory=get_emp_id)    city: str = field(init=False, default="patna", repr=True, hash=True) emp = employee("Satyam", "ksatyam858", 21)hash(emp)
Output:
28166796391311520
If false then it will not consider these field.
Python3
city: str = field(init=False, default="patna", repr=True, hash=False) # object of the classemp = employee("Satyam", "ksatyam858", 21)hash(emp)
Output:
6124029366977666702
compare: If true (the default), this field is included in the generated equality and comparison methods (__eq__(), __gt__().
Python3
# hashfrom dataclasses import dataclass, field # A class for holding an employees content@dataclass(unsafe_hash=True)class employee:     # Attributes Declaration    # using Type Hints    name: str    age: int    emp_id: str    city: str = field(init=False, default="patna",                      repr=True, hash=False, compare=True)  emp1 = employee("Satyam", "ksatyam858", 21)emp2 = employee("Kumar", "satyam.10151", 22)emp1 == emp2
Output:
False
metadata: This can be a mapping or None. None is treated as an empty dict.
Python3
# hashfrom dataclasses import dataclass, field # A class for holding an employees content@dataclass(unsafe_hash=True)class employee:     # Attributes Declaration    # using Type Hints    name: str    age: int    emp_id: str    city: str = field(init=False, default="patna", repr=True,                      metadata={'format': 'State'}) emp = employee("Satyam", "ksatyam858", 21)emp.__dataclass_fields__['city'].metadata['format']
 While creating object __post_init__() method call automatically. __init__() code will call a method named __post_init__().
Example: In an employee dataclass, if we want to check employee age, then we can define into the __post_init__() method.
Python3
# A basic Data Class# importing dataclass modulefrom dataclasses import dataclass, field  # A class for holding an employees content@dataclassclass employee:     # Attributes Declaration    # using Type Hints    name: str    emp_id: str    age: int    city: str     # post init function    def __post_init__(self):        if self.age >= 30:            self.check_age = True        else:            self.check_age = False  emp = employee("Satyam", "ksatyam858", 21, 'Patna')emp.check_age
Output:
False
Inheritance enables us to define a class that takes all the functionality from a parent class.
Example: Child class inherits the properties of the parent class.
Python3
# A basic Data Class# importing dataclass modulefrom dataclasses import dataclass, field  # parent class@dataclassclass Staff:    name: str    emp_id: str    age: int # child class@dataclassclass employee(Staff):    salary: int  emp = employee("Satyam", "ksatyam858", 21, 60000)emp
Output:
employee(name='Satyam', emp_id='ksatyam858', age=21, salary=60000)
saurabh1990aror
adnanirshad158
python-oop-concepts
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.