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

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -