如何编写一个超时装饰器,它可以获得一个函数或一个装饰函数?

如何编写一个超时装饰器,它可以获得一个函数或一个装饰函数?,第1张

概述我有以下超时创建装饰器功能: class TimeoutError(Exception): passdef timeout(seconds, error_message = 'Function call timed out'): def decorated(func): print "timeout: \t" + func.__name__ def _ 我有以下超时创建装饰器功能:

class TimeoutError(Exception): passdef timeout(seconds,error_message = 'Function call timed out'):    def decorated(func):        print "timeout: \t" + func.@R_502_4267@        def _handle_timeout(signum,frame):            raise TimeoutError(error_message)        def wrapper(*args,**kwargs):            signal.signal(signal.SIgalRM,_handle_timeout)            signal.alarm(seconds)            try:                print "timeout wrapper: \t" + func.@R_502_4267@                result = func(*args,**kwargs)            finally:                signal.alarm(0)            return result        return functools.wraps(func)(wrapper)    return decorated

另一个装饰者:

import inspectclass withHostAndToken(object):    @R_502_4267@ = "withHostAndToken"    __doc__ = "Get the Host and Token for the API call"    def __init__(self,func):        print "withHostAndToken: \t" + func.@R_502_4267@        self.func = func        self.HOST = ''        self.TOKEN = ''    def __call__(self,*args,**kwds):        if self.HOST == '':            self.HOST = "HOST"        if self.TOKEN == '':            self.TOKEN = "TOKEN"        argsspec = inspect.getargspec(self.func)        function_args = argsspec[0]        if 'HOST' in function_args:            if 'TOKEN' in function_args:                return self.func(self.HOST,self.TOKEN,**kwds)            else:                return self.func(self.HOST,**kwds)        elif 'TOKEN' in function_args:            return self.func(self.TOKEN,**kwds)

当我尝试将两者都应用于函数时,我不会得到要调用的函数代码:

@timeout(2)@withHostAndTokendef testDecorators():    print @R_502_4267@    while True:        print '.'testDecorators()

the output of this is:

withHostAndToken: testDecorators
timeout: withHostAndToken
timeout wrapper: withHostAndToken

Process finished with exit code 0

解决方法 你的问题不存在,装饰器的链接工作正常.

以下是与装饰器一起演示的示例代码:

>>> @timeout(2)@withHostAndTokendef bar(*args):    print(*args)    i = 0;    while True:        dummy = sys.stderr.write('.')>>> bar('foo')host token foo....................................................................................................................................................................................................................................................................................................................................................................................................................Traceback (most recent call last):  file "<pyshell#48>",line 1,in <module>    bar('foo')  file "<pyshell#2>",line 10,in wrapper    result = func(*args,**kwargs)  file "<pyshell#5>",line 19,in __call__    return self.func(self.HOST,**kwds)  file "<pyshell#47>",line 7,in bar    dummy = sys.stderr.write('.')... message List truncate for brIEvety ...  file "<pyshell#2>",line 4,in _handle_timeout    raise TimeoutError(error_message)TimeoutError: Function call timed out>>>

因此,按预期大约2秒后,该功能正确中断.

但在您的用例中,您在最内部函数中使用了time.sleep.在linux和其他Unix中,睡眠是通过… SIgalRM实现的!

所以这是发生的事情:

>外部装饰者要求在10秒钟内发出警报
>内部装饰器将附加参数传递给函数
>调用该函数并调用sleep(20)

>睡眠功能调用将闹钟超时重置为20秒!

这就是为什么这个功能实际上持续20秒而不是10秒…

总结

以上是内存溢出为你收集整理的如何编写一个超时装饰器,它可以获得一个函数或一个装饰函数?全部内容,希望文章能够帮你解决如何编写一个超时装饰器,它可以获得一个函数或一个装饰函数?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1196344.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存