如何编写一个超时装饰器,它可以获得一个函数或一个装饰函数?
发布时间:2020-12-20 13:19:03 所属栏目:Python 来源:网络整理
导读:我有以下超时创建装饰器功能: class TimeoutError(Exception): passdef timeout(seconds,error_message = 'Function call timed out'): def decorated(func): print "timeout: t" + func.__name__ def _handle_timeout(signum,frame): raise TimeoutError(
我有以下超时创建装饰器功能:
class TimeoutError(Exception): pass def timeout(seconds,error_message = 'Function call timed out'): def decorated(func): print "timeout: t" + func.__name__ 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.__name__ result = func(*args,**kwargs) finally: signal.alarm(0) return result return functools.wraps(func)(wrapper) return decorated 另一个装饰者: import inspect class withHostAndToken(object): __name__ = "withHostAndToken" __doc__ = "Get the Host and Token for the API call" def __init__(self,func): print "withHostAndToken: t" + func.__name__ 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) @withHostAndToken def testDecorators(): print __name__ while True: print '.' testDecorators()
解决方法
你的问题不存在,装饰器的链接工作正常.
以下是与装饰器一起演示的示例代码: >>> @timeout(2) @withHostAndToken def 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秒钟内发出警报 >睡眠功能调用将闹钟超时重置为20秒! 这就是为什么这个功能实际上持续20秒而不是10秒… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |