(python)在函数中使用装饰器进行彩色打印

我如何装饰一个函数,以便它打印到stdout的任何东西都是绿色的,打印到stderr的任何东西都是红色的?我有termcolor模块可用.

奖金业力:如何将参数传递给装饰器以指定颜色,将它们默认为红色和绿色?

最佳答案 一个有趣的问题.最简单的解决方案与Pete建议的类似.只需在将函数运行到每个stderr和stdout之前打印转义码.但是,如果stderr和stdout都是同一个终端,通常就是这种情况,它们会干扰.

因此,另一种解决方案是使用一个微小的包装器修补stdout和stderr,在每次写入的持续时间内启用颜色,只有当我们在终端(而不是管道)时才注意这一点.

#!/usr/bin/python2

import sys

def colorize(stdoutColor, stderrColor):
  defaultColor = '\033[0;0m'

  def applyColorize(f):
    class colorWrapper(object):
      def __init__(self, wrapee, color):
        self.wrapee = wrapee
        self.color = color
      def __getattr__(self, attr):
        if attr == 'write' and self.wrapee.isatty():
          return lambda x: self.wrapee.write(self.color + x + defaultColor)
        else:
          return getattr(self.wrapee, attr)

    def wrapper(*args, **kwds):
      oldStdout = sys.stdout
      oldStderr = sys.stderr
      sys.stdout = colorWrapper(oldStdout, stdoutColor)
      sys.stderr = colorWrapper(oldStderr, stderrColor)
      try:
        f(*args, **kwds)
      finally:
        sys.stdout = oldStdout
        sys.stderr = oldStderr

    return wrapper

  return applyColorize


greenColor = '\033[01;32m'
redColor = '\033[01;31m'

def foo():
  print "I'm ordinary and boring!"
  print >> sys.stderr, 'Writing to stderr!'

@colorize(greenColor, redColor)
def colorFoo():
  print "I'm colorful and exciting!"
  print >> sys.stderr, 'Writing to stderr!'

if __name__ == '__main__':
  foo()
  colorFoo()
  foo()

这仍然可以稍微改进一下,但它应该在大多数情况下完成工作并在适当后清理.当然,请记住我使用的是特定于shell的转义码.如果您想要可移植性,则必须使用对便携式终端控制模块的调用替换转义码写入.

点赞