【问题标题】:How could I override Python's print function to prepend some arbitrary text to every printed line?我如何覆盖 Python 的 print 函数以在每个打印行前添加一些任意文本?
【发布时间】:2020-03-10 23:37:41
【问题描述】:

我们更多地使用 AWS Lambda,但遇到了一个问题:很难确定哪些日志输出对应于哪个特定 Lambda 调用。我们看到官方AWS article online 建议将 AWS Lambda 请求 ID 添加到每个打印的日志行。在他们的示例代码中,他们手动将请求 ID 传递给每个日志调用。这样做似乎很痛苦。我们有 很多 代码需要更改,并且到处传递 request-id 将是一项挑战。我们还托管用户编写的代码,并希望他们可以免费使用print

所以我们想要做的是,每当调用 print() 时,实际的日志行都会以请求 ID 开头。这可以通过猴子补丁打印,或者(最好)将标准输出重定向到自定义文件处理程序。

【问题讨论】:

  • log 行使用 logging 模块。它已经具备自定义每条日志消息的功能。
  • 我最初没有这么说(但修改了答案说),但我们也在平台上托管用户编写的代码。我们希望他们可以免费使用 print() 而不是 Python 记录器模块。但你是对的,日志模块确实对此有一些支持。
  • 我认为没有理由不提供一个合适的logging.Formatter 供公众使用,让那些想使用print 的人自生自灭。
  • 不喜欢那个。考虑到平台的可用性,大多数 Python 程序员很早就被引入打印,而 logger 模块则要晚得多。我希望即使是 Python 的新用户也能在这个平台上感到自在。我们也需要捕获他们的日志输出。
  • 你是必须支持它的人。 logging 使用起来并不难,没有什么理由以不必要的灵活性为名去宠爱新用户。

标签: python python-3.x amazon-web-services logging


【解决方案1】:

我认为这应该可行。我们使用redirect_stdout 来捕获对标准输出的调用,然后将它们推送到我们的 PrintPrepender 自定义类中。

import sys
from contextlib import redirect_stdout
import os


class PrintPrepender:
    stdout = sys.stdout
    def __init__(self, text_to_prepend):
        self.text_to_prepend = text_to_prepend
        self.buffer = [self.text_to_prepend]
    def write(self, text):
        lines = text.splitlines(keepends=True)
        for line in lines:
            self.buffer.append(line)
            self.flush()
            if line.endswith(os.linesep):
                self.buffer.append(self.text_to_prepend)
    def flush(self, *args):
        self.stdout.write(''.join(self.buffer))
        self.stdout.flush()
        self.buffer.clear()

测试它:

import time

def test():
    buf = PrintPrepender('6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 ')
    with redirect_stdout(buf):
        print("hello ", end='', flush=True)
        time.sleep(1)
        print("world", end='', flush=True)
        time.sleep(1)
        print('.')
        print("lorem ipsum \n", flush=True)
        print("delor something")
        print("done")

test()

输出:

6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 hello world.
6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 lorem ipsum 
6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 
6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 delor something
6b59c9ff-2be3-4e8b-9f7a-7c018bc4cd38 done

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 2017-12-29
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多