
本文介绍在python中实现“每次运行脚本时自动创建新日志文件(如 log_file.txt、log_file1.txt、log_file2.txt)”的完整方案,涵盖文件名自增逻辑、路径安全处理、时间戳增强及异常防护。
本文介绍在python中实现“每次运行脚本时自动创建新日志文件(如 log_file.txt、log_file1.txt、log_file2.txt)”的完整方案,涵盖文件名自增逻辑、路径安全处理、时间戳增强及异常防护。
在实际开发中,为避免日志覆盖、便于问题追溯,常需为每次程序运行生成独立的日志文件。原始代码中使用固定文件名 "log_file.txt" 并以追加模式("a")写入,导致所有运行日志混杂于同一文件,且未使用 counter 变量——这正是无法实现“每次新建文件”的根本原因。
要实现动态命名(如 log_file.txt → log_file1.txt → log_file2.txt),核心思路是:在写入前扫描目标目录,找出已存在的同类日志文件,按序号递增生成下一个可用文件名。推荐使用 pathlib(现代、跨平台)或 glob(轻量兼容)完成文件探测。以下是优化后的完整实现:
import datetime
from pathlib import Path
def get_next_log_filename(base_name: str = "log_file", suffix: str = ".txt", directory: str = ".") -> str:
"""生成下一个可用的日志文件名,如 log_file.txt → log_file1.txt → log_file2.txt"""
dir_path = Path(directory)
dir_path.mkdir(exist_ok=True) # 确保目录存在
# 匹配所有形如 "log_file*.txt" 的文件(包括 log_file.txt 和 log_file1.txt 等)
pattern = f"{base_name}*[0-9]*{suffix}"
existing_files = list(dir_path.glob(pattern))
# 提取所有已用序号(log_file.txt 视为序号 0)
used_numbers = set()
for f in existing_files:
stem = f.stem
if stem == base_name: # 如 log_file.txt
used_numbers.add(0)
else:
# 尝试从末尾提取数字,如 log_file123 → 123
num_part = ""
for c in reversed(stem):
if c.isdigit():
num_part = c + num_part
else:
break
if num_part:
used_numbers.add(int(num_part))
# 找到最小未使用的正整数序号(从 1 开始尝试)
next_num = 1
while next_num in used_numbers:
next_num += 1
# 构建新文件名:首次运行用 log_file.txt,后续用 log_file1.txt、log_file2.txt...
if next_num == 1:
return str(dir_path / f"{base_name}{suffix}")
else:
return str(dir_path / f"{base_name}{next_num}{suffix}")
def log(message: str, base_name: str = "log_file", directory: str = "."):
"""写入日志到新生成的唯一文件"""
try:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_message = f"[{timestamp}] {message}\n"
filename = get_next_log_filename(base_name, ".txt", directory)
with open(filename, "w", encoding="utf-8") as f: # 使用 "w" 而非 "a"
f.write(log_message)
print(f"✅ 日志已写入: {filename}")
except Exception as e:
print(f"❌ 日志写入失败: {e}")
# 示例调用
if __name__ == "__main__":
log("程序启动,初始化完成")
log("用户登录成功")
log("数据处理完毕")
✅ 关键改进说明:
- 命名策略清晰:首次运行生成 log_file.txt,第二次生成 log_file1.txt,第三次 log_file2.txt,依此类推;
- 安全健壮:自动创建目录、显式指定 UTF-8 编码、使用 pathlib 提升可读性与跨平台兼容性;
- 避免歧义:通过反向解析数字后缀,正确识别 log_file10.txt 而非误判为 log_file1.txt;
- 语义明确:使用 "w" 模式确保每个日志文件仅记录单次运行内容,杜绝混杂。
⚠️ 注意事项:
- 若需按日期分组(如 log_20240520_001.txt),建议改用时间戳前缀 + 序号组合;
- 生产环境推荐使用 logging 模块配合 TimedRotatingFileHandler 或 RotatingFileHandler,更专业可靠;
- 多进程场景下需额外加锁,防止文件名冲突(本方案适用于单进程脚本)。
通过此方案,你将获得可预测、易管理、无覆盖风险的日志体系——每一次执行,都留下一份专属的运行快照。











