Cascading functions in Python using reduce and decorators -


i have method called render implemented subclass , called this:

class myclass(object):      def __call__(self, *args, **kwargs):          api_response = self.render(*args, **kwargs)          return api_response      def render(self, *args, **kwargs):         """ method implemented subclass."""             raise notimplementederror      def cascade_callables():         print 'ask awesome people @ stackoverflow solution problem.' 

i have list of callables [c1, c2, c3]. want inside cascade_callables method should this:

def cascade_callables():     callables = [c1, c2, c3]     callables.append(self.render)     self.render = reduce(some_decorator_that_accepts_two_functions, callables) 

so essentially, trying render work without modifying actual implementation:

c1(*args, **kwargs) c2(*args, **kwargs) c3(*args, **kwargs) render(*args, **kwargs) 

i tried work decorator me can use in reduce:

def cascade_modifiers(modifier1, modifier2):      def cascaded_modifier(self, *args, **kwargs):          modifier1(self, *args, **kwargs)         modifier2(self, *args, **kwargs)      return cascaded_modifier 

but got this:

typeerror: cascaded_modifier() takes @ least 1 argument (0 given) 

what best approach solve problem in python 2.7 using paradigm have tried explaining in question?

the trouble you're having you're saving new render method in instance variable. means won't self passed automatically, python's method binding uses descriptor protocol, , descriptors work if class variables.

so, need make sure callables bound (if need use self) , rewrite cascaded_modifier not expect self parameter. passing bound version of original render function, it's in case weren't going second copy of self!

note can simplify cascade_callables if use loop rather reduce. approach requires 1 fewer function:

def cascade_callables(self):     callables = [c1, c2, c3]   # these should bound methods if need self     callables.append(self.render)      def new_render(*args, **kwargs): # no self parameter here         c in callables:             c(*args, **kwargs)       # nor here      self.render = new_render 

if reason did need pass self callables, , there not practical way make them bound methods, things bit differently , use self parameter enclosing cascade_callables scope:

def cascade_callables(self):     callables = [c1, c2, c3]   # if these not bound, can work around issue     old_render = self.render   # 1 bound though can't mix in      def new_render(*args, **kwargs): # no self parameter here         c in callables:             c(self, *args, **kwargs) # here access enclosing scope's self         old_render(*args, **kwargs)  # needs called separately in version      self.render = new_render 

Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

android - Associate same looper with different threads -

visual studio 2010 - Connect to informix database windows form application -