简体   繁体   中英

How to toggle the action of a decorator in Python3

I have a decorator @newthread which wraps functions to run in a separate thread (using wraps from functools and Thread from threading ). However, there are some functions for which I only want this to happen some of the time.

At the moment, I have @newthread check the keyword arguments of the function to be wrapped and if it finds a bool new_thread equal to True then it runs the function in a separate thread, otherwise it runs the function normally. For example,

@newthread
def foo(new_thread=False)
     # Do stuff...

foo() # Runs normally
foo(new_thread=True) # Runs in new thread

Is this the canonical way of doing this, or am I missing something?

Don't use newthread as a decorator, then. A decorator is just a function that takes a function and returns a function.

If you want it to run in the current thread, call

foo(some, params)

If you want to run foo in a new thread, call

newthread(foo)(some, params)
@newthread
def foo(new_thread=False)
     # Do stuff...

foo() # Runs normally
foo(new_thread=True) # Runs in new thread

That is good - but, I for one, would prefer to have the decorator do consume the "new_thread" argument, instead of having it showing on the parameter list of the decorated functions.

Also, you could use a "default" value so that you'd pick the actual need to use a different thread from somewhere else (like an enviroment variable):

MARKER = object()
def newthread(func):
    def wrapper(*args, newthread=MARKER, **kwargs):
        if newthread is MARKER:
              newthread = os.environ.get("force_threads", True)
        if newthread:
             ...
             # cretae new thread and return future-like object
        else:
             return func(*args, **kwargs)
    return wrapper

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