Python:在个人标准输出上编辑文本 - 加倍文字

时间:2017-01-08 13:50:57

标签: python logging stdout

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

但问题显示当我尝试通过在其之前添加内容来编辑写入函数中的文本时。结果这" [堆叠]"在文本变量之前和之后添加。

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]

2 个答案:

答案 0 :(得分:4)

我在这个问题上摸不着头脑,直到我发现我应该通过调试器运行它。发生这种情况的原因是,当您使用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

修改

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

答案 1 :(得分:0)

如果您使用的是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()