Python has a library called attrs which makes code written in an object-oriented mode much easier and concise. In a class that has data, it is better to transform it into a dictionary. We can use attr.asdict() function in Python to return attrs attribute values of i as dict.
Syntax: attr.asdict (inst, recurse: bool=True, filter: __class__=None, dict_factory: , retain_collection_types: bool=False)
Parameters:
inst : instance of an attrs-decorated class
recurse : (boolean) recurse into classes that are also attrs-decorated
dict_factory : a callable to produce dictionaries from
filter : a callable that determines whether an attribute is included (True) or dropped (False)
retain_collection_types : only meaningful if recurse is True.
Example 1: Let’s take a very simple example of class coordinates which accepts coordinates as attributes.
Python3
# import library import attr # initialising class Coordinates, no need to # initialize __init__ method @attr .s class Coordinates( object ): # attributes x = attr.ib() y = attr.ib() c1 = Coordinates( 1 , 2 ) # converting data into dict using attr.asdict() # function print (attr.asdict(Coordinates(x = 1 , y = 2 ))) |
Output:
{'x': 1, 'y': 2}
Here, the data passed is getting converted into a dictionary form.
Example 2: Here is another example of class User Info which will accept the name and email id of the user as attributes, but will not include the email id of user in dict form of data.
Python3
import attr @attr .s class UserInfo( object ): users = attr.ib() @attr .s class User( object ): email = attr.ib() name = attr.ib() # including only name and not email attr.asdict(UserInfo([User( "lee@har.invalid" , "Lee" ), User( "rachel@har.invalid" , "Rachel" )]), filter = lambda attr, value: attr.name ! = "email" ) |
Output:
{'users': [{'name': 'Lee'}, {'name': 'Rachel'}]}
Here we will get a nested dictionary with email of user excluded.
Example 3: We can try a different approach for including or excluding an attribute by using the parameter filter of attr.asdict() function.
Python3
import attr @attr .s class UserInfo( object ): name = attr.ib() password = attr.ib() age = attr.ib() # excluding attributes print (attr.asdict(UserInfo( "Marco" , "abc@123" , 22 ), filter = attr.filters.exclude( attr.fields(UserInfo).password, int ))) @attr .s class Coordinates( object ): x = attr.ib() y = attr.ib() z = attr.ib() # inclusing attributes print (attr.asdict(Coordinates( 20 , "5" , 3 ), filter = attr.filters.include( int ))) |
Output:
{'name': 'Marco'} {'x': 20, 'z': 3}
Here, in class UserInfo, we have passed three arguments name, password, and age, out of which age is an integer value and the remaining values are string. In the filter parameter, we have excluded attributes – password and integer values(here -age), so password and age will be excluded from the dictionary.
In class Coordinates, we have passed three arguments- x, y, and z coordinates. Here y coordinate is passed as a string. In the filter parameter, we have included integer values. Thus, x and z coordinates are included in the final dictionary. If y-coordinate had been passed as an integer then it would have been included too.