如何在不修改原函数的情况下通过executor函数为demo函数的输出着色?
可行方案:不修改demo函数为其输出添加颜色
当然可以实现,核心思路是临时替换标准输出流(sys.stdout),捕获demo函数中print语句的输出内容,为其添加ANSI颜色控制码后再输出到控制台。以下是两种具体实现方式:
方式一:直接在executor中替换stdout
import sys def executor(f): print("This is executor") # 自定义输出处理器,负责给内容加颜色 class ColoredOutput: def write(self, text): # 过滤空输出(print会自动插入换行,可能产生空字符串) if text.strip(): # ANSI红色控制码:\x1b[31m 开启红色,\x1b[0m 恢复默认 colored_text = f"\x1b[31m{text.strip()}\x1b[0m\n" sys.__stdout__.write(colored_text) def flush(self): sys.__stdout__.flush() # 临时替换标准输出 original_stdout = sys.stdout sys.stdout = ColoredOutput() try: f() finally: # 无论执行是否出错,都恢复原输出流,避免影响后续代码 sys.stdout = original_stdout def demo(): print("This is demo function") executor(demo)
方式二:用上下文管理器封装(更简洁可复用)
import sys from contextlib import contextmanager # 封装颜色输出的上下文管理器 @contextmanager def colored_print(color_code): original_stdout = sys.stdout class ColoredWriter: def write(self, text): if text.strip(): # 根据传入的颜色码生成带颜色的内容 colored_content = f"\x1b[{color_code}m{text.strip()}\x1b[0m\n" sys.__stdout__.write(colored_content) def flush(self): sys.__stdout__.flush() sys.stdout = ColoredWriter() try: yield finally: sys.stdout = original_stdout def executor(f): print("This is executor") # 使用绿色输出(32是ANSI绿色码) with colored_print(32): f() def demo(): print("This is demo function") executor(demo)
关键说明
- ANSI颜色控制码:常用的前景色码包括
31(红)、32(绿)、33(黄)、34(蓝),\x1b[0m用于重置颜色,避免后续输出持续带颜色。 - 为什么用
sys.__stdout__:这是Python保存的原始标准输出流,直接写入它可以绕过我们自定义的输出处理器,避免循环调用。 - 异常安全:使用
try-finally确保无论demo函数执行是否抛出异常,都能恢复原始的标准输出流,不会影响程序后续的输出逻辑。
内容的提问来源于stack exchange,提问作者Parth Mandaliya
相关产品推荐
相关产品推荐

