I came across a situation where I had to implement a Python class which can;
- handle dynamic attributes
- can be initialized with a dictionary
- can be persisted on the local storage as a file
- can be used as a dictionary as well as a object. ( allow both foo['key'] and foo.key to access its attributes )
So I came up with this Class. It inherits from python’s built in Dictionary class ( dict ). Therefore it can be initialized with an existing dictionary. And it also overrides __getattr__ __setattr__ __delattr__ . Therefore it can handle dynamic attributes and act as a dictionary as well as a object. Finally It uses Python’s cPickle to serialize and persist it self in the local storage.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import cPickle as pickle class PersistableDictionary(dict): __getattr__ = dict.__getitem__ __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ def __init__(self, name, **dictionary): self.name = name if not dictionary: dictionary = self.load() super(PersistableDictionary, self).__init__(**dictionary) pass def load(self): try: pkl_file = open('{}.pkl'.format(self.name), 'rb') data = pickle.load(pkl_file) pkl_file.close() pass except IOError, e: data = {} pass return dict(data) pass def save(self): output = open('{}.pkl'.format(self.name), 'wb') pickle.dump(dict(self), output) output.close() pass pass if __name__ == '__main__': # initialize pd = PersistableDictionary("my_dict") # use as a normal dictionary pd['key_x'] = "value x" pd['key_y'] = "value y" # persist the dictionary pd.save() pd_copy = PersistableDictionary("my_dict") # acting as a dictionary for k in pd_copy: print "key : {} | value : {}".format(k, pd_copy[k]) # acting as a object print "value of {} is : {}".format("pd.key_x", pd.key_x) print "value of {} is : {}".format("pd.key_y", pd.key_y) pass |
Please share your thoughts on this approach. 🙂