python - How to define a super powerful class-style dict object? -


assume object meeting need called classdic, functions of instance of class classdic are:

  1. query, update, add, , delete data can realized in class style way , dict style way (called "two ways").

  2. when attribute or key not existing, instance of classdic can automatically build , make equal default value on both instance , dict, can query both ways (note: not add, query).

so, how can implement class?

the example below shows how instance of class work:

dic={'one':1, 'two':{'four':4,'five':{'six':6,'seven':7}}, 'three':3}  cdic=classdic(dic,default=100)  -------------------query in 2 ways------------------------------------------- >>> cdic.one 1 >>> cdic.two {'four':4,'five':{'six':6,'seven':7}} >>> cdic.two.five.six 6 >>> cdic['two']['five']['six'] 6 -------------------update in 2 ways------------------------------------------- >>> cdic['two']['five']['six']=7 >>> cdic.two.five.six 7 >>> cdic.two.five.six=8 >>> cdic['two']['five']['six'] 8 -------------------add in 2 ways------------------------------------------- >>> cdic['two']['five']['eight']=8 >>> cdic.two.five.eight 8 >>> cdic.two.five.nine=9 >>> cdic['two']['five']['nine'] 9 -------------------query default in 2 ways------------------------------------------- >>> print cdic['ten'] 100 >>> cdic.ten 100 >>> print cdic.eleven 100 >>> cdic['eleven'] 100 -------------------the final state of cdic------------------------------------------- >>> cdic {'eleven': 100, 'three': 3, 'two': {'four': 4, 'five': {'nine': 9, 'seven': 7, 'six': 8, 'eight': 8}}, 'ten': 100, 'one': 1} 

subclass collections.defaultdict():

from collections import defaultdict, mapping  class default_attribute_dict(defaultdict):     def __init__(self, *args, **kwargs):         super(default_attribute_dict, self).__init__(*args, **kwargs)         self.__dict__ = self      def __getattr__(self, name):         # trigger default         return self[name]      @classmethod     def from_dictionaries(cls, d, default=lambda: none):         cdic = cls(default)         key, value in d.iteritems():             if isinstance(value, mapping):                value = cls.from_dictionaries(value, default=default)             cdic[key] = value         return cdic 

this not automatically create nested instances of itself; you'll need loop on input dictionary , create nested objects yourself.

but offer attribute access , default values:

>>> cdic = default_attribute_dict(lambda: 100) >>> cdic.hundred 100 >>> cdic['ten'] = 10 >>> cdic.ten 10 >>> cdic['ten'] 10 

to build tree existing dictionary, use from_dictionaries() class method:

>>> cdic = default_attribute_dict.from_dictionaries(dic, default=lambda: 100) >>> cdic defaultdict(<function <lambda> @ 0x109998848>, {'one': 1, 'three': 3, 'two': defaultdict(<function <lambda> @ 0x109998848>, {'four': 4, 'five': defaultdict(<function <lambda> @ 0x109998848>, {'seven': 7, 'six': 6})})}) >>> cdic.two.four 4 

note keys on dictionary can mask methods; keep in mind when inserting keys match dictionary methods:

>>> cdic = default_attribute_dict.from_dictionaries(dic, default=lambda: 100) >>> cdic.keys <built-in method keys of default_attribute_dict object @ 0x7fdd0bcc9ac0> >>> cdic['keys'] 100 >>> cdic.keys 100 >>> cdic.keys() traceback (most recent call last):   file "<stdin>", line 1, in <module> typeerror: 'int' object not callable 

Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -