You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中@monitors类装饰器的实现方案咨询

Python中@monitors类装饰器的实现方案咨询

我来帮你实现这个@monitors装饰器,刚好能满足你要的监控逻辑——让监控函数在后台线程持续运行,直到被监控的函数执行完毕,而且完全不会阻塞主函数的执行。

实现思路

核心思路是利用线程+线程安全的事件标志来控制监控线程的生命周期:

  • 装饰器接收你定义的monitor函数作为参数
  • 当被装饰的函数启动时,开启一个后台线程,循环执行monitor函数
  • 用threading.Event来标记被监控函数是否执行完成,一旦完成,监控线程就停止循环
  • 被监控函数正常执行,不会被监控线程阻塞

完整实现代码

import threading
import time

def monitors(monitor_func):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 创建一个事件,用来通知监控线程停止
            stop_event = threading.Event()
            
            def monitor_loop():
                # 循环执行监控函数,直到收到停止信号
                while not stop_event.is_set():
                    monitor_func()
            
            # 启动监控线程,设置为守护线程,避免程序等待它结束
            monitor_thread = threading.Thread(target=monitor_loop, daemon=True)
            monitor_thread.start()
            
            try:
                # 执行被监控的主函数
                result = func(*args, **kwargs)
            finally:
                # 不管主函数正常结束还是抛出异常,都通知监控线程停止
                stop_event.set()
                # 等待监控线程完成当前的监控循环
                monitor_thread.join()
            
            return result
        return wrapper
    return decorator

# 你的监控函数
def monitor():
    """
    这个函数会在另一个线程中运行,直到`some_cool_function`执行完毕
    在示例中会执行5次(因为主函数sleep10秒,这里每次sleep2秒)
    完全不会阻塞主函数
    """
    print("    hi from monitor!")
    time.sleep(2)

# 被监控的函数
@monitors(monitor)
def some_cool_function():
    """
    @monitors装饰器会让监控函数在后台线程运行
    这个函数是阻塞的(正常执行自己的逻辑)
    """
    print("this should be instantaneous!")
    time.sleep(10)
    print("done!")

if __name__ == '__main__':
    some_cool_function()

代码关键点解释

  1. 带参数的装饰器:monitors是一个装饰器工厂,先接收monitor_func,再返回真正的装饰器,这样你就能把自定义的监控函数传进去。
  2. 线程安全的停止标志:threading.Event是线程安全的,主函数执行完毕后调用stop_event.set(),监控线程的循环就会终止。
  3. 守护线程:把监控线程设置为daemon=True,这样即使主程序意外结束,监控线程也会自动退出,配合finally块的主动停止逻辑,双重保障避免线程泄漏。
  4. 异常兼容:用try-finally确保不管被监控函数是正常结束还是抛出异常,监控线程都会被正确停止。

运行效果

执行代码后,你会看到和你期望一致的输出:

this should be instantaneous!
    hi from monitor!
    hi from monitor!
    hi from monitor!
    hi from monitor!
    hi from monitor!
done!

主函数立刻打印第一行,然后监控函数每隔2秒打印一次,一共5次,最后主函数打印"done!",完全符合你的需求。

备注:内容来源于stack exchange,提问作者kehrazy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:17:56