【问题标题】:Python: Editing text on personal stdout - doubled textPython:在个人标准输出上编辑文本 - 双倍文本
【发布时间】:2017-01-08 13:50:56
【问题描述】:

我需要将与控制台中显示的日志相同的日志保存到文件中,因此我编辑了 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]

【问题讨论】:

  • print "Test log" 被执行为write("Test log")write("\n") - 所以你得到write("[stack]" + "Test log")write("[stack]" + "\n")。尝试使用逗号print "Test", "log",你会得到更多[stack] - [stack]Test[stack] [stack]log[stack] :)

标签: python logging stdout


【解决方案1】:

我在这个问题上摸不着头脑,直到我认为我应该通过调试器运行它。发生这种情况的原因是,当您使用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("Test", "log"),你会得到[stack]Test[stack] [stack]log :) 它仍然需要一些工作。
  • @furas 发现得很好,我在上面。
  • 所以...祝你好运。 :)
  • @furas 我想我明白了。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多