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
Post a Comment