Prerequisite: Data Classes in Python Set 1 | Set 2
In this post we will discuss how to modify certain properties of the attributes of DataClass object, without explicitly writing code for it using field
function.
field()
function –
dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None)
The MISSING
value is a sentinel object used to detect if the default
and default_factory
parameters are provided. This sentinel is used because None
is a valid value for default
. No code should directly use the MISSING
value.
default: This parameter specifies the default value for the attribute, if no value is provided during object creation. Similar to the parameters in a function, fields with a default value must come after any fields without a default.
There is also an alternative way to provide a default value – just like you do to a normal variable using = operator. (Line #9 in below code)
from dataclasses import dataclass, field @dataclass class GfgArticle: title: str author: str language: str = field(default = 'Python3' ) upvotes: int = 0 # A DataClass object article = GfgArticle( "DataClass" , "vibhu4agarwal" ) print (article) |
Output:
GfgArticle(title='DataClass', author='vibhu4agarwal', language='Python3', upvotes=0)
default_factory : If provided, it must be a zero-argument callable that will be called when a default value is needed for this field.
The return value of the callable will be set as the default value for the attribute in object creation.
You either provide a callable to the default factory OR you provide a default value to the attribute. It is an error to specify both default and default_factory.
from dataclasses import dataclass, field from random import choice def get_default_language(): languages = [ 'Python3' , 'Java' , "CPP" ] return choice(languages) @dataclass class GfgArticle: title: str author: str language: str = field(default_factory = get_default_language) upvotes: int = 0 # A DataClass object article = GfgArticle( "DataClass" , "vibhu4agarwal" ) print (article) |
The above code puts one of the Python3, Java or CPP as default value for language while DataClass object creation.
The init, repr and hash parameters are similar to that in the dataclass function as discussed in previous article. compare parameter can be related to order as that in dataclass function. The difference is being in their ability to be applicable only to a particular attribute, not to all the attributes in the DataClass under the decorator.
init : If true (the default), this field is included as a parameter to the generated __init__() method. A way to set default value should be provided when init
is set to False
.
repr : If true (the default), this field is included in the string returned by the generated __repr__() method.
compare : If true (the default), this field is included in the generated equality and comparison methods (__eq__(), __gt__(), et al.).
from dataclasses import dataclass, field @dataclass class GfgArticle: title: str = field(compare = False ) author: str = field( repr = False ) language: str = field(default = 'Python3' ) upvotes: int = field(init = False , default = 0 ) # DataClass objects # Note the difference in their title value article1 = GfgArticle( "DataClass" , "vibhu4agarwal" ) article2 = GfgArticle( "Python Packaging" , "vibhu4agarwal" ) print (article1) print (article1.author) print (article1 = = article2) |
Output:
GfgArticle(title='DataClass', language='Python3', upvotes=0) vibhu4agarwal True
hash : This can be a bool
or None
. If true, this field is included in the generated __hash__() method. If None
(the default), use the value of compare
: this would normally be the expected behavior.
A field should be considered in the hash if it’s used for comparisons. Setting this value to anything other than None
is discouraged.
metadata : This is usually a dictionary, the key-value pair indicating various information and it’s data.
This particular attribute does not really seem to be in use most of the times but it’s important if your DataClass is actually being in used somewhere during development and the attribute’s data is used or accessed by third-parties when their tool or software is integrated in the project.
In the script, it’s value can be accessed by querying __dataclass_fields__ variable of the object.
from dataclasses import dataclass, field @dataclass class GfgArticle: title: str = field(compare = False ) author: str = field(metadata = { 'data' : 'Profile Handle' }) language: str = field(default = 'Python3' ) upvotes: int = field(init = False , default = 0 ) # A DataClass object article = GfgArticle( "DataClass" , "vibhu4agarwal" ) print (article) print (article.__dataclass_fields__[ 'author' ].metadata) |
Output:
GfgArticle(title='DataClass', author='vibhu4agarwal', language='Python3', upvotes=0) {'data': 'Profile Handle'}