簡體   English   中英

(python) 在 function 中使用裝飾器進行彩色打印

[英](python) colour printing with decorator in a function

如何裝飾 function 使其打印到stdout的任何內容為綠色,打印到stderr的任何內容為紅色 我有可用的termcolor模塊。

額外的業力:如何將 arguments 傳遞給裝飾器以指定顏色,默認為紅色和綠色?

一個有趣的問題。 最簡單的解決方案類似於 Pete 的建議。 只需在運行 function 到每個標准錯誤和標准輸出之前打印轉義碼。 但是,如果 stderr 和 stdout 都輸入同一個終端,通常情況下,它們會干擾。

因此,另一種解決方案是使用一個微型包裝器對標准輸出和標准錯誤進行猴子補丁,該包裝器在每次寫入期間啟用顏色,僅當我們在終端中(而不是管道)時才注意這樣做。

#!/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 的轉義碼。 如果您想要可移植性,則必須將轉義代碼寫入替換為對便攜式終端控制模塊的調用。

這是我使用 termcolor 模塊的代碼:

from termcolor import colored

class ColoredOutput:
    def __init__(self, org_handle, color, on_color=None, attrs=['bold']):
        self.org_handle = org_handle
        def wrapper_write(x):
            return org_handle.write(colored(x, color=color, on_color=on_color, attrs=attrs))
        self.wrapper_write = wrapper_write
    def __getattr__(self, attr):
        return self.wrapper_write if attr == 'write' else getattr(self.org_handle, attr)

if __name__ == '__main__':
    import sys
    import colorama   # I'm working under windows 7, so i need this module to enable terminal color

    colorama.init()
    sys.stderr = ColoredOutput(sys.stderr, 'red')
    print('This is a test string', file=sys.stderr)

這適用於我 Mac 的 Terminal.app 中的 Bash

import sys
green = '\033[01;32m'
red = '\033[01;31m'

sys.stdout.write(green+"Hello ")
sys.stderr.write(red+"world!")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM