Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

programmatically add "decorators" to python functions

I have put decorators in quotes as these aren't strict decorators by python standards although they need to act like one.

Let's say I have 3 decorators, f,g,h.

def f(x):
   return x+1

def g(x):
   return x+2

def h(x):
   return x * 3

and my "real" fn

def orig_fn(z):
   return z + 100

How can I modify orig_fn so that I can chain at runtime different combinations of f,g,h ?

If I use more than one of f,g,h then they should all be applied - ie orig_fn may return f(g(orig_fn(x)) .

I've tried something like (the real thing I'm doing is modifying a class function - hence the inclusion of MethodType). fn_chain would be something like [f,g] and I'm trying to solve this generically - current_fn is the original function found in the class.

 if fn_chain:
   print "-> creating chain"
   for fn in fn_chain:
     def modified_fn(self,*args,**kwargs):
       return fn(self, current_fn, *args,**kwargs)
                #current_fn = modified_fn

     setattr(cls,f_name,types.MethodType(modified_fn,cls))
like image 449
Richard Green Avatar asked Mar 21 '26 05:03

Richard Green


1 Answers

It's simple enough to build a function for composing other functions:

def compose(*funcs):
    # If we compose(f, g), we want to apply g first.
    funcs = funcs[::-1]

    def composition(val):
        for func in funcs:
            val = func(val)
        return val

    return composition

Then you can call compose(f, g, orig_fn) to get a function that does f(g(orig_fn(x))).

like image 78
user2357112 supports Monica Avatar answered Mar 23 '26 18:03

user2357112 supports Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!