Understanding Python Dataclasses
Last Updated :
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.
DataClass in Python
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
class employee:
def __init__( self , name, emp_id, age, city):
self .name = name
self .emp_id = emp_id
self .age = age
self .city = city
def __repr__( self ):
return ( "employee (name={}, emp_id={}, age={}, city={} )"
. format ( self .name, self .emp_id, self .age, self .city))
def __eq__( self , check):
return (( self .name, self .emp_id, self .age, self .city) = =
((check.name, check.emp_id, check.age, check.city)))
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)
print ()
print ( "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 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
from dataclasses import dataclass
@dataclass
class employee:
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)
print ()
print ( "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.
dataclasses.Field()
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
@dataclass
class employee:
name: str
emp_id: str
age: int
city: str
emp = 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
from dataclasses import dataclass, field
@dataclass
class employee:
name: str
emp_id: str
age: int
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
from dataclasses import dataclass, field
def get_emp_id():
id = 2345
return id
@dataclass
class employee:
name: str
age: int
emp_id: str = field(default_factory = get_emp_id)
city: str = field(default = "patna" )
emp = 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
from dataclasses import dataclass, field
@dataclass
class employee:
name: str
age: int
emp_id: str
city: str = field(init = False , default = "patna" )
emp = 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
from dataclasses import dataclass, field
@dataclass
class employee:
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
from dataclasses import dataclass, field
@dataclass (unsafe_hash = True )
class employee:
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 )
emp = 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
from dataclasses import dataclass, field
@dataclass (unsafe_hash = True )
class employee:
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
from dataclasses import dataclass, field
@dataclass (unsafe_hash = True )
class employee:
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' ]
|
Post-init processing
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
from dataclasses import dataclass, field
@dataclass
class employee:
name: str
emp_id: str
age: int
city: str
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
DataClass Inheritance
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
from dataclasses import dataclass, field
@dataclass
class Staff:
name: str
emp_id: str
age: int
@dataclass
class employee(Staff):
salary: int
emp = employee( "Satyam" , "ksatyam858" , 21 , 60000 )
emp
|
Output:
employee(name='Satyam', emp_id='ksatyam858', age=21, salary=60000)
Share your thoughts in the comments
Please Login to comment...