Package: attribdict
AttribDictIntroductionAttribDict is an easy to use and easy to read dict, it is more flexible and human readable.Examples>>>fromattribdictimportAttribDictasDict>>>_d={"attr"+str(i):iforiinrange(4)}>>>d=Dict(_d)# create a AttribDict instance from a dict>>>print(d)attr0:0attr1:1attr2:2attr3:3You can also recursively create an attribute from other data type includingdict:# continue to previous code>>>d.attr4.subattr1.subsubattr1={1,2,4}# recursively create attribute>>>d.attr5.subattr1={"subsubattr"+str(i):iforiinrange(3)}# recursively create from a dict>>>print(d)attr0:0attr1:1attr2:2attr3:3attr4:-subattr1:-subsubattr1:{1,2,4}attr5:-subattr1:-subsubattr0:0-subsubattr1:1-subsubattr2:2Additionally,AttribDictalso support create attributes from a recursivelydict:# continue to previous code>>>_d={"_attr1":{"_subattr1":{"_subsubattr1":"hello attribdict"}}}# create attributes from a recursively dict>>>d._attr=_d>>>print(d)attr0:0attr1:1attr2:2attr3:3attr4:-subattr1:-subsubattr1:{1,2,4}attr5:-subattr1:-subsubattr0:0-subsubattr1:1-subsubattr2:2_attr:-_attr1:-_subattr1:-_subsubattr1:helloattribdictIf you want to convert an AttribDict instance into a pythondict, just use.as_dictmethod:# continue to previous code>>>_dict=d.as_dict()>>>print(_dict){'attr0':0,'attr1':1,'attr2':2,'attr3':3,'attr4':{'subattr1':{'subsubattr1':{1,2,4}}},'attr5':{'subattr1':{'subsubattr0':0,'subsubattr1':1,'subsubattr2':2}},'_attr':{'_attr1':{'_subattr1':{'_subsubattr1':'hello attribdict'}}}}You can also access value in traditionaldictway, for example:>>>print(d["_attr"].as_dict()){'_attr1':{'_subattr1':{'_subsubattr1':'hello attribdict'}}}Please feel free if you want to access value in following style:>>>print(d._attr["_attr1"]._subattr1["_subsubattr1"])helloattribdictAttribDict instance is iterable, thus you can useforstatement and so on to iteratively visit the attributes and corresponding values. Note that it will return (attribute, value) pair, sub-AttribDict will be converted to a pythondictfor more convenient use:# continue to previous code>>>forkey,valueind:...print("key: ",key)...print("value: ",value)...key:attr0value:0key:attr1value:1key:attr2value:2key:attr3value:3key:attr4value:{'subattr1':{'subsubattr1':{1,2,4}}}key:attr5value:{'subattr1':{'subsubattr0':0,'subsubattr1':1,'subsubattr2':2}}key:_attrvalue:{'_attr1':{'_subattr1':{'_subsubattr1':'hello attribdict'}}}Here is another example about iterable, the rest code is omitted:>>>it=iter(d)>>>next(it)('attr0',0)>>>next(it)('attr1',1)>>>next(it)('attr2',2)AttribDict offers two ways to copy and deepcopy an instance:>>>importcopy>>>d_copy=d.copy()>>>print(d._attrisd_copy._attr)True>>>copy_d=copy.copy(d)>>>print(d._attriscopy_d._attr)>>>True>>>d_deepcopy=d.deepcopy()>>>print(d._attrisd_deepcopy._attr)False>>>print(d.attr4.subattr1.subsubattr1isd_deepcopy.attr4.subattr1.subsubattr1)False>>>deepcopy_d=copy.deepcopy(d)>>>print(d._attrisdeepcopy_d._attr)>>>False>>>print(d.attr4.subattr1.subsubattr1isdeepcopy_d.attr4.subattr1.subsubattr1)FalseIf you want to check whether an object contains attributeattrX, please useobj.hasattr("attrX")buthasattr(obj, "attrX")as the latter one will create a new AttribDict instance namedattrX.>>>d.hasattr("attrX")False>>>hasattr(d,"attrX")TruePickling AttribDict instance.>>>importpickle>>>withopen("path2file","wb")asfp:>>>...pickle.dump(d,fp)>>>...>>>withopen("path2file","rb")asfp:>>>...loaded_d=pickle.load(fp)>>>...>>>loaded_d==dTrue>>>loaded_disdFalseInstallationYou can install AttribDict by pip.pip install attribdict