Jupyter Notebook中无需重构实现print()同步输出至stdout与带时间戳日志器
实现print()输出同步到标准输出和带时间戳的日志记录器
核心思路
通过重定向sys.stdout,自定义一个双输出流,让所有print()的内容既输出到原标准输出(Jupyter的单元格输出区),同时被日志记录器捕获并添加时间戳保存,无需修改原有print()语句。
具体实现代码
import sys import logging import io # 1. 配置日志记录器 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(message)s', # 包含时间戳的日志格式 handlers=[ logging.FileHandler('print_logs.log'), # 日志写入文件 logging.StreamHandler() # 可选:同时输出到控制台 ] ) # 2. 自定义双输出流类 class DualOutputStream(io.TextIOBase): def __init__(self, original_stdout): self.original_stdout = original_stdout def write(self, text): # 输出到原标准输出(Jupyter单元格) self.original_stdout.write(text) # 将内容写入日志(过滤空行,避免日志冗余) if text.strip(): logging.info(text.strip()) def flush(self): self.original_stdout.flush() # 3. 替换sys.stdout为自定义流 original_stdout = sys.stdout sys.stdout = DualOutputStream(original_stdout) # 测试原有print语句 print("数据处理完成") print("当前进度:80%") # 可选:恢复原stdout(后续不需要双输出时执行) # sys.stdout = original_stdout
关键细节说明
- 日志配置:可根据需求调整
format自定义日志格式,修改handlers决定日志输出位置(仅文件/仅控制台/两者同时)。 - 空行处理:
write方法中过滤了空字符串,避免print()自带的换行符导致日志出现空行。 - 恢复原输出流:如果后续不需要双输出机制,执行
sys.stdout = original_stdout即可恢复默认行为,不影响其他代码。
效果验证
运行代码后:
- Jupyter单元格会正常显示
print()的内容; - 同级目录下的
print_logs.log文件中会生成带时间戳的日志,示例如下:
2024-05-20 15:42:10,345 - 数据处理完成
2024-05-20 15:42:10,346 - 当前进度:80%
内容的提问来源于stack exchange,提问作者Gordon Erlebacher
相关产品推荐
相关产品推荐

