简体   繁体   中英

Python decorator for multiple functions as arguments?

I get the basic principle of Python decorators and I like the syntax. However, they seem a little limited on what you can do.

Is there an elegant way to go about handling multiple functions as arguments like below?

def parent_fn(child_fn1, child_fn2):
    def wrapper():
        print('stuff is happening here')
        child_fn1()
        print('other stuff is happening here')
        child_fn2()
    return wrapper

@parent_fn
def decorated():
    print('child_fn1 stuff here')

decorated()

Where could I put the child_fn2 code? The few ideas I have tried appears to take away from the simplicity and elegance of the decorator.

You could do that:

import functools

def sequence_with(f):
    def wrap(g):
        @functools.wraps(g)
        def sequenced_func():
            f()
            g()
        return sequenced_func
    return wrap

def func1():
    print('func1')

@sequence_with(func1)
def func2():
    print('func2')

but it's probably not a good conceptual fit for decorators. Conceptually, decorators are supposed to alter the functionality of a single function they decorate; a function that sequences two other functions on an equal footing may not make much sense as a decorator. For example, the new function created by the decorator is now under the name func2 , replacing the original func2 . That only makes sense for some specific use cases, whereas avoiding decorator syntax would give you more flexibility.

It makes more sense to not use decorator syntax:

def sequence(f, g):
   def sequenced_func():
       f()
       g()
   return sequenced_func

def func1():
    print('func1')

def func2():
    print('func2')

sequenced_func = sequence(func1, func2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM