Python passing in a list of parameters to be used as dynamic properties -
i have specific jinja2 templating within flask(but not related either, context i'm working in construct more general):
class multiplemacrofor(object): def __init__(self, macro): self.macro = macro def renderable(self, macro_var): return get_template_attribute(self.macro, macro_var) class responseitemmacros(multiplemacrofor): def __init__(self): super(responseitemmacros, self).__init__(macro="macros/response_items.html") @property def general_macro(self): return self.renderable('general_macro') ri = responseitemmacros() an example use case:
ri.general_macro # returns renderable 'general_macro' 'macros/response_items.html' can used in jinja2 template which want turn this:
class multiplemacrofor(object): def __init__(self, macro, which_macros): self.macro = macro self.which_macros = which_macros # take which_macros , have them each returnable in function above # respond more general case, not requiring construction # @property # def (passed in var which_macro)(self): # return self.renderable(passed in var which_macro) ri = multiplemacrofor(macro="macros/response_items.html", macros=['general', 'etc', 'etal']) then use case:
ri.general_macro #as above without having construct intermediate responseitemsmacros class and have list passed in called property, dynamically contructed based on passed in list , not manually constructed first example. first example requires manually constructing 2 classes instance want use. second wish use 1 class can instanced properties called, work through renderable function produce relevant named macro.
only don't know how atm. input appreciated.
you can't have per-instance properties (or @ least not without messing get_attribute, should avoid). simplest solution use getattr.
class multiplemacrofor(object): def __init__(self, macro, names): self._macro = macro self._names = names def get_renderable(self, macro_var): return get_template_attribute(self.macro, macro_var) def __getattr__(self, name): if name in self._names: return self.get_renderable(name) raise attributeerror( "object %s has no attribute '%s'" % ( type(self).__name__, name) ) a more involved way dynamically build subclass instanciate it.
class multiplemacrofor(object): def __init__(self, macro, names): self._macro = macro self._names = names def get_renderable(self, macro_var): return get_template_attribute(self.macro, macro_var) def multiplemacroforfactory(macro, names): attrs = dict() name in names: attrs[name] = property( lambda self, name=name: self.get_renderable(name) ) clsname = "multiplemacrofor%s" % "".join( name.capitalize() name in names ) return type(clsname, (multiplemacrofor,), attrs)(macro, names)
Comments
Post a Comment