装饰器定义
import os
import signal
import functools
import threading
def default_timeout_handle():
raise Exception('执行函数超时')
def set_timeout(timeout, callback=default_timeout_handle):
"""
设置函数超时时间
:param timeout: 超时时间,单位s
:param callback: 回调函数
:return:
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if os.name == 'nt': # Windows
# 使用 threading 来实现超时功能
result = [Exception('执行函数超时')]
def target():
try:
result[0] = func(*args, **kwargs)
except Exception as e:
result[0] = e
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
callback()
thread.join() # 确保子线程能够退出
if isinstance(result[0], Exception):
raise result[0]
return result[0]
else: # Unix/Linux
def handle(signum, frame):
callback()
old_handler = signal.signal(signal.SIGALRM, handle)
signal.alarm(timeout)
try:
result = func(*args, **kwargs)
finally:
signal.signal(signal.SIGALRM, old_handler)
signal.alarm(0)
return result
return wrapper
return decorator
装饰器使用
import time
def long_running_function(seconds):
print(f"开始执行一个可能需要 {seconds} 秒的函数...")
time.sleep(seconds) # 模拟长时间运行的操作
print("函数执行完成。")
return "结果"
@set_timeout(5)
def long_running_function_with_timeout(seconds):
return long_running_function(seconds)
# 调用带有超时的函数
try:
result = long_running_function_with_timeout(10) # 设置为10秒,超过5秒超时
print(f"函数返回的结果是: {result}")
except Exception as e:
print(f"捕获到异常: {e}")
输出
开始执行一个可能需要 10 秒的函数...
捕获到异常: 执行函数超时