【问题标题】:Python flush a print statementPython刷新打印语句
【发布时间】:2014-03-26 00:25:38
【问题描述】:

我最近想要一些 python 代码,它可以让我输出到控制台和具有相同打印语句的日志文件。谷歌搜索后,我发现this 网站提供了一个很好的解决方案。但是,我希望能够在每次写入后刷新输出缓冲区,以便在日志文件中看到它。我将如何将它添加到这个类中?

我已尝试按照设置...

class output_file(object):
  def __init__(self, stdout, filename):
    silentremove(filename)
    self.stdout = stdout
    self.logfile = open(filename, "a")

def write(self, text):
    self.stdout.write(text)
    self.logfile.write(text)
    sys.stdout.flush()

  def flush(self):
    sys.stdout.flush()

  def close(self):
    self.stdout.close()
    self.logfile.close()

这是一个循环错误,导致刷新函数调用自身。

class output_file(object):
  def __init__(self, stdout, filename):
    silentremove(filename)
    self.stdout = stdout
    self.logfile = open(filename, "a")

  def write(self, text):
    self.stdout.write(text)
    self.logfile.write(text)
    self.stdout.flush()

  def flush(self):
    sys.stdout.flush()

  def close(self):
    self.stdout.close()
    self.logfile.close()

这根本没有冲洗它。

【问题讨论】:

  • 不回答问题,但您可能想查看日志记录模块。为了做你想做的事,你可以为同一个记录器定义两个处理程序(一个用于控制台,一个用于文件)
  • @RedBaron 这正是我最初想要的。如果您将其作为答案提交,我会接受。
  • 从技术上讲,这不是您问题的答案,因此我不适合发布它。对于未来的访问者,您可以在问题的尾声中解释 logging 如何帮助您克服最初的问题(导致了这个问题)

标签: python stdout flush logfile


【解决方案1】:

以下以非缓冲模式重新打开 sys.stdout。每个stdout.writeprint 之后都会自动刷新(即打印到标准输出)。

import sys
import os

# Flush STDOUT continuously
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

os.fdopen 的第三个参数是缓冲参数,0 是无缓冲的,1 是行缓冲的,>1 将产生(大约)该大小(以字节为单位)的缓冲区,<0将使用系统默认值。

更新

不允许使用 Python 3 无缓冲文本,即以下

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

会导致错误

ValueError: Can't have unbuffered text I/O

要在python3中使用无缓冲I/O,可以使用字节,即

sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)

在 python3 中可以正常工作。

【讨论】:

  • 为了稍后恢复到 sys.stdout 的原始行为:sys.stdout 仍然可以作为 sys.__stdout__ 使用。
  • sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
  • 更全面的答案在这里:*.com/questions/107705/python-output-buffering
  • ValueError: can't have unbuffered text I/O
  • 感谢您的快速更新。在空闲时遇到此问题,PyCharm..可以解决它