Python 中如何一个 print 语句同时输出到屏幕且记录到文件里 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
gaayyy
V2EX    程序员

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

  •  
  •   gaayyy 2017-09-06 22:40:02 +08:00 22354 次点击
    这是一个创建于 3011 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    23 条回复    2021-02-28 09:36:00 +08:00
    Trim21
        1
    Trim21  
       2017-09-06 22:40:52 +08:00
    覆写一下 print 函数
    0ZXYDDu796nVCFxq
        2
    0ZXYDDu796nVCFxq  
       2017-09-06 22:44:00 +08:00 via iPhone   1
    tee 命令
    a87150
        3
    a87150  
       2017-09-06 22:47:21 +08:00
    def pl(x):
    print(x)
    log(x)
    misaka19000
        4
    misaka19000  
       2017-09-06 22:48:25 +08:00   3
    NoAnyLove
        5
    NoAnyLove  
       2017-09-06 22:51:32 +08:00
    #4 的 Monkey patch 很巧妙,赞一个
    misaka19000
        6
    misaka19000  
       2017-09-06 22:51:59 +08:00   1
    虽然 V 站的编辑器很烂,还是把代码放上来吧
    ```python
    iport 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
        7
    gaayyy  
    OP
       2017-09-06 22:52:47 +08:00
    @Trim21
    @a87150
    不太希望动这个 print 函数,有的 print 的参数还不太一样,萌新不敢随便操作。

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

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

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

    楼主应该是被 python 的 stdout 缓冲坑了,直接 | tee 或者 > 重定向到文件 这样信息输出不是“实时”的,只有等 buffer 满了才会输出,中途 ctrl+c 中断了甚至会丢失一些输出。运行 python 时关闭缓冲就可以了,不需要改代码,毕竟一个个 print 去修改太麻烦,万一第三方模块中有黑魔法就坑大了。
    gaayyy
        21
    gaayyy  
    OP
       2017-09-08 21:37:50 +08:00
    @Osk 是的,要满 4k 才写入文件,这个当时直接重定向就发现了。。。 感谢大佬的详细解释。

    @gouchaoer 感谢大佬指点,2>&1 是把 stderr 也重定向到 stdout 吧。Linux 下面的小工具是真心好用,不过我们这套东西有时候还要在 windows 下面用,毕竟 nvidia 的官配是 windows 平台。JS 我这种萌新不适合,太容易掉坑里了。
    qq191513
        22
    qq191513  
       2018-08-13 22:43:59 +08:00
    拿走不用谢我~
    def print_and_save_txt(str=None,filename=r'log.txt'):
    with open(filename, "a+") as log_writter:
    print(str)
    log_writter.write(str)
    oldbird
        23
    oldbird  
       2021-02-28 09:36:00 +08:00
    @gaayyy 请问最后如何做到实时写入文件和屏幕显示的?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2397 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 15:51 PVG 23:51 LAX 07:51 JFK 10:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86