用户多次重绘图片标注框时如何覆盖Python日志仅保留最终坐标
实现方案
你现在用的logging默认是追加写模式,无法直接定向覆盖文件中某一条旧记录,可选择以下两种方案实现需求:
方案1:内存缓存标注结果,统一写入(最推荐)
该方案性能最优,适合标注量较大的场景:
- 首先在GUI类中新增缓存属性,用来存储所有图片的最新标注结果,键为图片文件名,值为标注信息:
# 在类的__init__方法中初始化 self.annotation_cache = {}
- 每次用户完成某张图片的标注绘制时,直接更新缓存,同文件名的旧值会自动被覆盖:
if file_name in self.loaded_boxes: p1, p2 = self.current_drag_box if p1 is not None and p2 is not None: # 更新缓存 from datetime import datetime self.annotation_cache[file_name] = { "update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")[:-3], "box": self.loaded_boxes[file_name] }
- 选择合适的时机全量覆盖写入日志文件,比如用户点击保存按钮、切换图片、关闭程序时:
def save_annotations_to_log(): log_lines = [] for fname, info in self.annotation_cache.items(): log_line = f"{info['update_time']} - root - DEBUG - {fname} box drawn at {info['box']}\n" log_lines.append(log_line) # 全量覆盖写入mylog.log with open("mylog.log", "w", encoding="utf-8") as f: f.writelines(log_lines)
- 不需要留存的调试日志(比如点击坐标日志)可以保留输出到test.log,不影响标注记录文件。
方案2:实时修改日志文件(适合标注量小的场景)
如果需要每完成一次标注就实时更新日志,可以每次写入前先过滤旧记录:
- 新增日志更新函数:
def update_single_annotation_log(file_name, new_box): log_path = "mylog.log" # 读取所有旧日志,过滤掉当前文件的旧标注记录 valid_lines = [] try: with open(log_path, "r", encoding="utf-8") as f: for line in f: if f"{file_name} box drawn at" not in line: valid_lines.append(line) except FileNotFoundError: # 首次运行文件不存在时跳过读取 pass # 拼接新的日志行 from datetime import datetime new_log_line = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]} - root - DEBUG - {file_name} box drawn at {new_box}\n" valid_lines.append(new_log_line) # 覆盖写入整个文件 with open(log_path, "w", encoding="utf-8") as f: f.writelines(valid_lines)
- 替换原有的日志打印代码即可:
if file_name in self.loaded_boxes: p1, p2 = self.current_drag_box if p1 is not None and p2 is not None: update_single_annotation_log(file_name, self.loaded_boxes[file_name])
注意事项
你现有代码中同时配置了root logger写入test.log、自定义handler写入mylog.log,如果不想标注记录同时出现在两个日志文件中,建议为mylog.log单独创建一个独立命名的logger实例,避免日志重复输出。
内容的提问来源于stack exchange,提问作者new2python
相关产品推荐
相关产品推荐

