Python 中如何一个 print 语句同时输出到屏幕且记录到文件里

2017-09-06 22:40:02 +08:00
 gaayyy

有一个第三方提供的脚本,一直在用,里面很多功能也封装的很好。唯一的缺憾就是他没有使用 log 模块,全部是 print 语句输出。

现在老板想把所有 print 的输出全部实时的保存到一个文本文件中,又不能影响现有的屏幕输出,感觉比较困难。

我试过用管道重定向:python cudaCFD.py > result.txt 发现只有在最后程序全部退出的时候才会把输出一次性写入到这个 result.txt 文件里面,而且这个方法也不能同时在屏幕的命令行中输出。

希望各位 python 大佬指导一下,谢谢。

21586 次点击
所在节点    程序员
23 条回复
Trim21
2017-09-06 22:40:52 +08:00
覆写一下 print 函数
gstqc
2017-09-06 22:44:00 +08:00
tee 命令
a87150
2017-09-06 22:47:21 +08:00
def pl(x):
print(x)
log(x)
misaka19000
2017-09-06 22:48:25 +08:00
NoAnyLove
2017-09-06 22:51:32 +08:00
#4 的 Monkey patch 很巧妙,赞一个
misaka19000
2017-09-06 22:51:59 +08:00
虽然 V 站的编辑器很烂,还是把代码放上来吧
```python
import sys


class Logger(object):
def __init__(self, filename="Default.log"):
self.terminal = sys.stdout
self.log = open(filename, "a")

def write(self, message):
self.terminal.write(message)
self.log.write(message)

def flush(self):
pass


sys.stdout = Logger("yourlogfilename.txt")
print("Hello world !") # this is should be saved in yourlogfilename.txt
```
gaayyy
2017-09-06 22:52:47 +08:00
@Trim21
@a87150
不太希望动这个 print 函数,有的 print 的参数还不太一样,萌新不敢随便操作。

@gstqc
目测这个能解决问题,谢谢大佬

最后纠正一点,那个 python cudaCFD.py > result.txt 不是最后一次性输出的,而是每满 4k 字节就写一次文件,我第一次操作输出不满 4k 所以得到的是个空的文件。
gaayyy
2017-09-06 22:55:00 +08:00
@misaka19000
大佬的实现方法目测很优雅,however,大佬的英语比较渣,this should be saved in xxx, 你写多了一个 is
flaneurse
2017-09-06 22:55:08 +08:00
with open('file', 'wa') as f:,这里不确定要不要覆盖原文件还是添加新的输出
print(result, file=f)
print(result)
Python2 的话,导入下__future__
mxi1
2017-09-06 22:57:46 +08:00
在代码里面,尽量用 Logger,少用 print。
PythonAnswer
2017-09-06 23:00:56 +08:00
logging 是解决方案。
gaayyy
2017-09-06 23:01:26 +08:00
@mxi1 第三方提供的,科学计算用的,写的人不是专业的程序员,但是确实是需要这个东西来算,算法什么的都在里面,一堆矩阵运算全部在里面,不敢动。。。
Osk
2017-09-06 23:03:02 +08:00
楼主的问题很好解决,任一即可:
python -u xxx.py
export PYTHONUNBUFFERED=y ; xxx.py
PYTHONUNBUFFERED=y xxx.py

再配合 tee 就 ok 啦
gaayyy
2017-09-06 23:07:28 +08:00
@misaka19000 再请教一下大佬,如果按照你这个 class,需要在最后调用一下 flush 函数么?是不是要 flush 一下才会写入到文件?
oott123
2017-09-07 09:02:14 +08:00
tee 呗
python xxx.py | tee log.txt
不需要改一行代码
xiaozizayang
2017-09-07 09:07:06 +08:00
print("hello", file= open("./1.txt", 'a'))
fluyy
2017-09-07 13:54:15 +08:00
用 logger 啊,定义输出到文件和控制台,我就是这么搞得
gouchaoer
2017-09-07 17:35:39 +08:00
python test.py 2>&1 | tee -a $log_file
就这么简单,非侵入式
gouchaoer
2017-09-07 17:38:57 +08:00
都写了那么多 print 了,怎么改成 logger 啊
我给你推荐一门语言 javascript,那个函数随便你改
Osk
2017-09-07 23:10:32 +08:00
回复用 管道+tee 的朋友来踩坑了。

楼主应该是被 python 的 stdout 缓冲坑了,直接 | tee 或者 > 重定向到文件 这样信息输出不是“实时”的,只有等 buffer 满了才会输出,中途 ctrl+c 中断了甚至会丢失一些输出。运行 python 时关闭缓冲就可以了,不需要改代码,毕竟一个个 print 去修改太麻烦,万一第三方模块中有黑魔法就坑大了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/388763

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX