简体   繁体   English

如何基于python中的特定条件将参数动态传递给decorator?

[英]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. 我已经用名为--- 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. 我的要求基于要发送timeout_in_seconds到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 意思是,如果keyword =='this_one',则real_time_reading函数应在30秒后超时;如果keyword =='that_one',则real_time_reading函数应在60秒后超时。

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'''

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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