Sunday, 15 September 2013

python - Class decorator to auto-update properties dictionary on disk? -



python - Class decorator to auto-update properties dictionary on disk? -

i working on project have number of custom classes interface varied collection of info on user's system. these classes have properties user-facing attributes. of these properties decently resource intensive, want run generation code once, , store returned value on disk (cache it, is) faster retrieval on subsequent runs. stands, how accomplishing this:

def stored_property(func): """this ``decorator`` adds on-disk functionality `property` decorator. decorator method decorator. each key property of class stored in settings json file dictionary of property names , values (e.g. :class:`myclass` stores properties in `my_class.json`). """ @property @functools.wraps(func) def func_wrapper(self): print('running decorator...') try: var = self.properties[func.__name__] if var: # property written disk homecoming var else: # property written disk `null` homecoming func(self) except attributeerror: # `self.properties` not yet exist homecoming func(self) except keyerror: # `self.properties` exists, property not key homecoming func(self) homecoming func_wrapper class myclass(object): def __init__(self, wf): self.wf = wf self.properties = self._properties() def _properties(self): # name of class in underscore format class_name = convert(self.__class__.__name__) # library used (in alfred workflows) interacted info stored on disk properties = self.wf.stored_data(class_name) # if no file on disk, or 1 of properties has null value if properties none or none in properties.values(): # names of properties of class propnames = [k (k, v) in self.__class__.__dict__.items() if isinstance(v, property)] properties = dict() prop in propnames: # generate dictionary of property names , values properties[prop] = getattr(self, prop) # utilize external library save dictionary disk in json format self.wf.store_data(class_name, properties, serializer='json') # homecoming either info read file, or info generated in situ homecoming properties #this decorator ensures generating code run if necessary @stored_property def only_property(self): # code info homecoming 'this property'

this code works exactly need it, still forces me manually add together _properties(self) method each class wherein need functionality (currently, have 3). want way "insert" functionality class please. think class decorator job done, seek might, can't quite figure out how wrangle it.

for sake of clarity (and in case decorator not best way want), seek explain overall functionality after. want write class contains properties. values of these properties generated via various degrees of complex code (in 1 instance, i'm searching app's pref file, searching 3 different preferences (any of may or may not exist) , determining best single result preferences). want body of properties' code contain algorithm finding data. but, don't want run algorithmic code each time access property. 1 time generate value once, want write disk , read on subsequent calls. however, don't want each value written own file; want dictionary of values of properties of single class written 1 file (so, in illustration above, my_class.json contain json dictionary 1 key, value pair). when accessing property directly, should first check see if exists in dictionary on disk. if does, read , homecoming value. if exists, has null value, seek run generation code (i.e. code written in property method) , see if can find (if not, method homecoming none , 1 time 1 time again written file). if dictionary exists , property not key (my current code doesn't create possible, improve safe sorry), run generation code , add together key, value pair. if dictionary doesn't exist (i.e. on first instantiation of class), run generation code properties , create json file. ideally, code able update 1 property in json file without rerunning of generation code (i.e. running _properties() again).

i know bit peculiar, need speed, human-readable content, , elegant code together. not have compromise on goal. hopefully, description of want clear enough. if not, allow me know in comment doesn't create sense , seek clarify. think class decorator me there (essentially inserting _properties() method class, running on instantiation, , mapping value properties attribute of class).

maybe i'm missing something, doesn't seem _properties method specific properties given class has. i'd set in base of operations class , have each of classes @stored_property methods subclass that. don't need duplicate _properties method.

class propertybase(object): def __init__(self, wf): self.wf = wf self.properties = self._properties() def _properties(self): # before... class myclass(propertybase): @stored_property def expensive_to_calculate(self): # calculate here

if reason can't subclass propertybase straight (maybe need have different base of operations class), can utilize mixin. failing that, create _properties take instance/class , workflow object , phone call explicitly in __init__ each class.

python class decorator

No comments:

Post a Comment