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

使用Watchdog监听文件夹文件修改时自定义函数无法触发的问题

使用Watchdog监听文件修改时函数调用失效的问题解决

我用Watchdog库监听指定文件夹的文件修改事件,期望文件改动时自动运行Python脚本。已创建项目文件夹、激活venv,脚本也放置在目标文件夹内。

示例代码如下:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pandas as pd

def on_modified(event):
    print("modified")
    test()

def test():
    print("test")

if __name__ == "__main__":
    path = 'C:/Users/MyUser/Desktop/Watchdog_test'
    event_handler = FileSystemEventHandler()

    event_handler.on_modified = on_modified

    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    try:
        print("monitoring")
        while True:
            time.sleep(3)
    except KeyboardInterrupt:
        observer.stop()
        print("Done")
    observer.join()

当前代码能正常启动并打印monitoring,修改文件夹内文件时终端也会输出modified,但test()函数完全没被触发。实际场景中,我在on_modified里调用trigger_all_functions()执行多个业务函数,同样遇到调用失效的问题:

def on_modified(event):
    print("modified")
    trigger_all_functions()

def trigger_all_functions():
    function1(...)
    ... = function2(...)

问题原因及修复方案

1. 重复触发的事件干扰

Windows系统下,修改文件时Watchdog会多次触发on_modified事件(比如文件保存时会先创建临时文件再替换,触发多次修改事件),后续事件可能打断前一次的函数执行,导致看起来函数没运行。

修复方式:给on_modified添加防抖逻辑,忽略短时间内的重复事件:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pandas as pd

last_trigger_time = 0
DEBOUNCE_DELAY = 1  # 防抖间隔,单位秒

def on_modified(event):
    global last_trigger_time
    current_time = time.time()
    # 跳过重复触发的事件
    if current_time - last_trigger_time < DEBOUNCE_DELAY:
        return
    last_trigger_time = current_time
    
    print("modified")
    test()

def test():
    print("test")

if __name__ == "__main__":
    path = 'C:/Users/MyUser/Desktop/Watchdog_test'
    event_handler = FileSystemEventHandler()
    event_handler.on_modified = on_modified

    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    try:
        print("monitoring")
        while True:
            time.sleep(3)
    except KeyboardInterrupt:
        observer.stop()
        print("Done")
    observer.join()

2. 函数执行异常被静默

如果test()或trigger_all_functions()内部存在报错,Watchdog默认不会打印异常信息,会让你误以为函数没被调用。

修复方式:给函数调用添加try-except捕获异常并打印:

def on_modified(event):
    print("modified")
    try:
        test()
    except Exception as e:
        print(f"调用test()出错: {e}")

def test():
    print("test")
    # 若有业务逻辑,这里的报错会被捕获并输出

3. 采用继承FileSystemEventHandler的规范写法

直接给event_handler.on_modified赋值的方式虽可行,但更规范的做法是继承FileSystemEventHandler并重写方法,避免潜在的事件冲突:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pandas as pd

class MyHandler(FileSystemEventHandler):
    last_trigger_time = 0
    DEBOUNCE_DELAY = 1

    def on_modified(self, event):
        current_time = time.time()
        if current_time - self.last_trigger_time < self.DEBOUNCE_DELAY:
            return
        self.last_trigger_time = current_time
        
        print("modified")
        try:
            self.test()
        except Exception as e:
            print(f"函数执行出错: {e}")

    def test(self):
        print("test")

if __name__ == "__main__":
    path = 'C:/Users/MyUser/Desktop/Watchdog_test'
    event_handler = MyHandler()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    try:
        print("monitoring")
        while True:
            time.sleep(3)
    except KeyboardInterrupt:
        observer.stop()
        print("Done")
    observer.join()

内容的提问来源于stack exchange,提问作者OneHotEncoder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:47:35