简体   繁体   中英

How to pass argument to decorator dynamically based on certain condition in python?

I have written a timeout decorator function with the file named --- timeout.py.

from functools import wraps
import errno
import os
import signal

class TimeoutError(Exception):
    pass

def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)
        @wraps(func)
        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wrapper

    return decorator

Now I have another file which has the following code in a different file

"""some code at the starting"""
if keyword == 'this_one':
    real_time_reading(this_one)    #how to send timeout_in_seconds dynamically
elif keyword == 'that_one':
    real_time_reading(this_one)

@timeout(timeout_in_seconds)
def real_time_reading(keyword):
    '''Here it does some operations and if there is no input
       it times out based on the timeout_in_seconds value given
       to decorator'''

My requirement is based on the keyword I want to send timeout_in_seconds to decorator.

Meaning, if keyword== 'this_one' then, the real_time_reading function should time out after 30 seconds and if keyword== 'that_one' then, the real_time_reading function should time out after 60 seconds

Is there a way to send decorator arguments dynamically based on certain condition?

No, the decorator is initialised when the function is parsed. There might be ways to dynamically alter (hack) it, but that would have undesired consequences.

I suggest using two functions:

"""some code at the starting"""
if keyword == 'this_one':
    real_time_reading_this_one(keyword)
elif keyword == 'that_one':
    real_time_reading_that_one(keyword)

@timeout(timeout_in_seconds)
def real_time_reading_this_one(keyword)
    return _real_time_reading(keyword);

@timeout(timeout_in_seconds * 2)
def real_time_reading_that_one(keyword)
    return _real_time_reading(keyword);

def _real_time_reading(keyword):
    '''Here it does some operations and if there is no input
       it times out based on the timeout_in_seconds value given
       to decorator'''

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