我有以下超时创建装饰器功能:
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 , *args, **kwds)
else:
return self.func(self.HOST , *args, **kwds)
elif 'TOKEN' in function_args:
return self.func(self.TOKEN, *args, **kwds)
当我尝试将两者都应用于函数时,我没有得到要调用的函数代码:
@timeout(2)
@withHostAndToken
def testDecorators():
print __name__
while True:
print '.'
testDecorators()
输出是:
withHostAndToken:testDecorators
超时:withHostAndToken
超时包装器:withHostAndToken处理完成,退出代码为0
答案 0 :(得分:0)
你的问题并不存在,装饰的链接工作正常。
以下是一个使用装饰器演示的示例代码:
>>> @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 , self.TOKEN , *args, **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中,sleep
是通过...... SIGALRM
!
所以这是发生的事情:
sleep(20)
sleep
函数调用将警报超时重置为20秒!这就是为什么这个功能实际上持续20秒而不是10 ...
的原因