(蟒蛇)彩色印刷
问题描述:
我如何装饰功能,使任何它打印到stdout
是绿色和任何它打印到stderr
是红色?我有termcolor
模块可用。(蟒蛇)彩色印刷
Bonus karma:如何将参数传递给装饰者以指定颜色,并将它们默认为红色和绿色?
答
一个有趣的问题对我的作品在猛砸。最简单的解决方案与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的转义码。如果您需要便携性,则必须将呼叫转义码替换为便携式终端控制模块。
答
这在我的Mac的Terminal.app
import sys
green = '\033[01;32m'
red = '\033[01;31m'
sys.stdout.write(green+"Hello ")
sys.stderr.write(red+"world!")
+2
你不需要使用后缀吗?当你这样做时,所有终端输出保持绿色或红色 – 2012-11-06 07:34:11
答
这里是我的代码以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)
装饰影响的装饰功能,不能完全不相关的功能,如'sys.stdout.write'。定义'write_to_stdout(line,color = green)'并使用它来代替'print'会容易得多。你可以在一个函数内部替换stdout,但是这看起来非常黑客并且与线程断开。 – 2011-06-01 03:40:54
@Jochen:无论stdout是否被覆盖,从多个线程打印到同一个流,都会导致输出混乱,因此它是无关紧要的,创建一个特殊的write_to_stdout()函数并不能解决Python(Python )从你的脚本调用库打印到标准输出。至于hackiness,每次使用管道时都会重定向标准输出。这是一个非常正常的方法。 – 2011-06-01 04:14:26