Python:编辑个人标准输出上的文本 - 双文本

Python: Editing text on personal stdout - doubled text

我需要将控制台中显示的日志保存到文件中,因此我编辑了 sys.stdout。 (使用 Redirect stdout to a file in Python? 中的代码)

但是当我试图通过在它之前添加一些东西来编辑写入函数中的文本时,问题就出现了。结果这个“[stack]”在文本变量前后添加。

import sys

class Logger(object):
    def __init__(self):
        self.terminal = sys.stdout
        self.file = open("log.txt", "a")
    def flush(self):
        self.terminal.flush()
        self.file.flush()
    def write(self, text):
        self.terminal.write("[stack]" + text)
        self.file.write(text)
        self.flush();

sys.stdout = Logger()

print "Test log"
print "Another test log"

结果:

[stack]Test log[stack]
[stack]Another test log[stack]

如果您正在使用 Python3,您可以重载内置 print 来自定义输出。下面的代码给你预期的输出:

import sys
import builtins

class Logger(object):
    def __init__(self):
        self.terminal = sys.stdout
        self.file = open("log.txt", "a")
    def flush(self):
        self.terminal.flush()
        self.file.flush()
    def write(self, text):
        self.terminal.write(text)
        self.file.write(text)
        self.flush();

def myprint(string):
  builtins.print("%s%s" % ("[stack]", string))

print = myprint

sys.stdout = Logger()

我一直在为这个问题绞尽脑汁,直到我认为我应该 运行 通过调试器来处理它。发生这种情况的原因是当您使用 print 时,它会尝试写入文本正文以及配置的 end,默认情况下是换行符。

因此,每个 print 语句都会导致对 Logger.write 的两次单独调用,一次是(例如)Test Log,第二次是 \n。这导致输出 [stack] Test Log[stack]\n.

这是更正后的实现:

import sys


class Logger(object):
    def __init__(self, stream, default_sep=' ', default_end='\n'):
        self.terminal = stream
        self.default_sep = default_sep
        self.default_end = default_end
        self.continuing_same_print = False
        self.file = open("log.txt", "a")

    def flush(self):
        self.terminal.flush()
        self.file.flush()

    def write(self, text):
        if text is self.default_end:
            self.continuing_same_print = False
        elif text is self.default_sep:
            self.continuing_same_print = True

        new_text = text
        if text in {self.default_sep, self.default_end}:
            pass
        elif self.continuing_same_print:
            pass
        else:
            new_text = '[stack]' + new_text

        self.terminal.write(new_text)
        self.file.write(text)
        self.flush()


sys.stdout = Logger(sys.stdout)

print("Test", "log")
print("Another test log")
print()

输出

[stack]Test log
[stack]Another test log

编辑

更新了实现以支持在打印语句中打印多个对象。