Python3.x实现轻量级定时检测文件变更任务的最优方案是什么?
认知偏差纠正
- Python 中单开常驻线程处理轻量定时任务的资源开销远低于预期:单个空线程仅占用几十KB内存,3秒一次的文件状态检测CPU占用几乎可以忽略,对于小型应用来说完全不存在「资源浪费」的问题,是性价比极高的实现方案。
可选轻量级解决方案
方案1:标准库asyncio实现(无额外依赖、无需单独常驻线程)
如果你的主程序可以接入asyncio事件循环,直接把定时检测任务挂载到全局事件循环即可,完全不需要额外开辟线程:
import asyncio import os # 配置要检测的文件路径,存储上次修改时间 file_mtimes = { "path/to/file1": 0, "path/to/file2": 0 } async def check_file_change(): while True: changed_files = [] for file_path, last_mtime in file_mtimes.items(): current_mtime = os.path.getmtime(file_path) if current_mtime > last_mtime: changed_files.append(file_path) file_mtimes[file_path] = current_mtime if changed_files: # 此处自定义文件变更后的业务逻辑 print(f"检测到文件变更: {changed_files}") await asyncio.sleep(3) async def your_other_business(): # 此处写你的其他业务逻辑,和检测任务并行运行 while True: print("主业务运行中") await asyncio.sleep(1) async def main(): await asyncio.gather( check_file_change(), your_other_business() ) if __name__ == "__main__": asyncio.run(main())
方案2:标准库threading实现(代码最简、兼容性最好)
如果你的主程序是同步逻辑,不想改造为异步架构,直接用线程实现就足够简单轻量:
import threading import time import os file_mtimes = { "path/to/file1": 0, "path/to/file2": 0 } stop_event = threading.Event() def check_file_change(): while not stop_event.is_set(): changed_files = [] for file_path, last_mtime in file_mtimes.items(): current_mtime = os.path.getmtime(file_path) if current_mtime > last_mtime: changed_files.append(file_path) file_mtimes[file_path] = current_mtime if changed_files: print(f"检测到文件变更: {changed_files}") time.sleep(3) # 启动检测守护线程,主程序退出时自动销毁 t = threading.Thread(target=check_file_change, daemon=True) t.start() # 你的其他主业务逻辑 while True: print("主业务运行中") time.sleep(1) # 需要停止检测时调用 stop_event.set() 即可
方案3:轻量第三方依赖watchdog(性能最优、无需轮询)
如果可以接受安装极小的第三方依赖,watchdog是专门做文件系统监听的库,总大小不到100KB,不需要自行轮询,文件变更时会主动触发回调,性能远高于定时轮询:
import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler # 配置要监听的文件列表 WATCH_FILES = ["path/to/file1", "path/to/file2"] class FileChangeHandler(FileSystemEventHandler): def on_modified(self, event): if not event.is_directory and event.src_path in WATCH_FILES: print(f"检测到文件变更: {event.src_path}") if __name__ == "__main__": event_handler = FileChangeHandler() observer = Observer() # 监听文件所在的目录 observer.schedule(event_handler, path="path/to/file/directory", recursive=False) observer.start() # 你的其他主业务逻辑 try: while True: print("主业务运行中") time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
内容的提问来源于stack exchange,提问作者Raj Kumar Singh
相关产品推荐
相关产品推荐

