Crossin的编程教室

告别手动刷新,用Python实现目录监听

大家好,欢迎来到 Crossin 的编程教室。

在开发自动化脚本时,我们常遇到这种痛点:每当新数据文件存入文件夹,或者修改了配置文件,都必须手动重新运行脚本才能生效。

这种“手动触发”不仅低效,且极易遗漏。虽然可以用 while True 循环去轮询文件时间戳,但写起来麻烦,运行间隔短了浪费 CPU 资源,长了又响应不及时。

为了优雅地解决这个问题,watchdog 库应运而生。它就像一个时刻站岗的哨兵,一旦文件夹内发生任何风吹草动,都能立刻触发预设的动作。

核心功能

watchdog 的高性能源于它直接调用了操作系统的内核接口(如 Linux 的 inotify、Windows 的 ReadDirectoryChangesW)。在实际代码中,主要由两个组件协同工作:

1. 事件处理器 (Event Handler)

负责定义“做什么”。通过继承 FileSystemEventHandler,你可以重写特定的方法:

on_modified():文件内容或元数据被修改时触发。

on_created():新文件或目录诞生时触发。

on_deleted():文件被删除时触发。

2. 观察者 (Observer)

负责定义“盯着谁”。它在一个独立的线程中运行,负责监听系统信号并将其派发给处理器。

示例演示

为了更直接地展示 watchdog 的功能,我们将创建一个“自动化监控器”,实时追踪目录下文件的创建与修改情况。

1. 环境准备

pip install watchdog

2. 完整代码

你可以将以下内容保存为 monitor.py 并运行:

import timeimport sysfrom watchdog.observers import Observerfrom watchdog.events import FileSystemEventHandler
# 1. 定义事件处理器class MyHandler(FileSystemEventHandler):    def on_modified(self, event):        if not event.is_directory:            print(f"【修改】文件:{event.src_path}")
    def on_created(self, event):        tag = "文件夹" if event.is_directory else "文件"        print(f"【新建】{tag}:{event.src_path}")
# 2. 核心控制逻辑if __name__ == "__main__":    path = "."  # 监控当前目录    event_handler = MyHandler()    observer = Observer()
    # recursive=True 表示递归监控子目录    observer.schedule(event_handler, path, recursive=True)
    print(f"哨兵已就位,正在监控: {path}")    observer.start()
    try:        while True:            time.sleep(1) # 保持主线程存活    except KeyboardInterrupt:        observer.stop()
    observer.join()

代码说明:

  • MyHandler 继承了基类。通过 event.is_directory 属性,我们可以轻松区分出变动的是普通文件还是文件夹。

  • observer.start() 会启动一个后台线程。这意味着监控逻辑不会阻塞你主程序的其他业务逻辑。

  • recursive=True 是个双刃剑,它能帮你盯着所有子文件夹,但在处理海量小文件的项目(如 node_modules)时需要慎用。

  • 使用 try...except 捕获 KeyboardInterrupt(即 Ctrl+C),确保在程序停止时能正常关闭后台线程。

注意事项

在进阶使用 watchdog 时,有一些细节和优化建议能帮你少走弯路:

  • 某些编辑器(如 VS Code)保存文件时会先创建临时文件再覆盖,这可能导致一次保存触发两次 on_modified。建议在代码中加入时间戳判断,过滤掉连续多次的改动。

  • 不要在事件处理函数里写耗时太长的逻辑(比如上传大文件)。建议使用队列(Queue)将任务传出去,让监控线程尽可能简单。

常用场景

watchdog 主要用于各种可自动触发操作的场景,比如:

  • 开发辅助:代码改动后自动运行单元测试。

  • 办公自动化:监控下载目录,根据文件后缀名自动归档。

  • 安全报警:监控敏感配置文件,防止被恶意篡改。

掌握了 watchdog,你就等于拥有了一套通用的“文件触发工作流”。你可以将这个模块化思路应用到任何需要实时响应的项目中,让你的 Python 脚本“动”起来。

最后留个思考题:如果想在监控到 .log 文件产生时自动把它备份到一个叫做 logs_backup 的目录里,要怎么做?来动手试试看吧。

如果本文对你有帮助,欢迎点赞、评论、转发。你们的支持是我更新的动力~


添加微信 crossin123 ,加入编程教室共同学习~
Image
感谢转发和点赞的各位~