Package: diot
Python dictionary with dot notation (A re-implementation ofpython-boxwith some issues fixed and simplified)fromdiotimportDiotmovie_data={"movies":{"Spaceballs":{"imdb stars":7.1,"rating":"PG","length":96,"director":"Mel Brooks","stars":[{"name":"Mel Brooks","imdb":"nm0000316","role":"President Skroob"},{"name":"John Candy","imdb":"nm0001006","role":"Barf"},{"name":"Rick Moranis","imdb":"nm0001548","role":"Dark Helmet"}]},"Robin Hood: Men in Tights":{"imdb stars":6.7,"rating":"PG-13","length":104,"director":"Mel Brooks","stars":[{"name":"Cary Elwes","imdb":"nm0000144","role":"Robin Hood"},{"name":"Richard Lewis","imdb":"nm0507659","role":"Prince John"},{"name":"Roger Rees","imdb":"nm0715953","role":"Sheriff of Rottingham"},{"name":"Amy Yasbeck","imdb":"nm0001865","role":"Marian"}]}}}# Box is a conversion_box by default, pass in `conversion_box=False` to disable that behavior# Explicitly tell Diot to convert dict/list insidemovie_diot=Diot(movie_data)movie_diot.movies.Robin_Hood_Men_in_Tights.imdb_stars# 6.7movie_diot.movies.Spaceballs.stars[0].name# 'Mel Brooks'# Different as box, you have to use Diot for new data in a listmovie_diot.movies.Spaceballs.stars.append(Diot({"name":"Bill Pullman","imdb":"nm0000597","role":"Lone Starr"}))movie_diot.movies.Spaceballs.stars[-1].role# 'Lone Starr'Installpipinstall-UdiotAPIhttps://pwwang.github.io/diot/api/diot/UsageDiotInstantiated the same ways asdictDiot({'data':2,'count':5})Diot(data=2,count=5)Diot({'data':2,'count':1},count=5)Diot([('data',2),('count',5)])# All will create# Diot([('data', 2), ('count', 5)], diot_nest = True, diot_transform = 'safe')Same aspython-box,Diotis a subclass of dict which overrides some base functionality to make sure everything stored in the dict can be accessed as an attribute or key value.diot=Diot({'data':2,'count':5})diot.data==diot['data']==getattr(diot,'data')By default, diot uses a safe transformation to transform keys into safe names that can be accessed bydiot.xxxdt=Diot({"321 Is a terrible Key!":"yes, really"})dt._321_Is_a_terrible_Key_# 'yes, really'Different aspython-box, duplicate attributes are not allowed.dt=Diot({"!bad!key!":"yes, really",".bad.key.":"no doubt"})# KeyErrorUse different transform functions:dt=Diot(oneTwo=12,diot_transform='snake_case')# or use alias:# dt = SnakeDiot(oneTwo = 12)dt.one_two==dt['one_two']==dt['oneTwo']==12dt=Diot(one_two=12,diot_transform='camel_case')# or use alias:# dt = CamelDiot(one_two = 12)dt.oneTwo==dt['one_two']==dt['oneTwo']==12dt=Diot(one_two=12,diot_transform='upper')dt.ONE_TWO==dt['one_two']==dt['ONETWO']==12dt=Diot(ONE_TWO=12,diot_transform='lower')dt.one_two==dt['ONE_TWO']==dt['one_two']==12Use your own transform function:importinflectiondt=Diot(post=10,diot_transform=inflection.pluralize)dt.posts==dt['posts']==dt['post']==10OrderedDiotdiot_of_order=OrderedDiot()diot_of_order.c=1diot_of_order.a=2diot_of_order.d=3list(diot_of_order.keys())==['c','a','d']# insertion allowed for OrderedDiotod=OrderedDiot()od.insert(0,"c","d")od.insert(None,"x","y")od.insert_before('c',"e","f")od.insert_after("a",("g","h"))od2=OrderedDiot()od2.a1='b1'od2.c1='d1'od.insert(-1,od2)od3=OrderedDiot()od3.a2='b2'od3.c2='d2'od.insert_before('c',od3)FrozenDiotfd=FrozenDiot(a=1,b=3)fd.c=3# DiotFrozenErrorwithfd.thaw():fd.c=3fd.c==3Missing key handlerd=Diot(a=1,b=2,diot_missing=ValueError)d['c']# ValueErrord.c# AttributeError from ValueErrord=Diot(a=1,b=2,diot_missing=ValueError("Custom message"))d=Diot(a=1,b=2,diot_missing=None)# d.c is Noned=Diot(a=1,b=2,diot_missing=lambdakey,diot:diot.a+diot.b)# d.c == 3