[英](python) colour printing with decorator in a function
How can I decorate a function so that anything it prints to stdout
is in green and anything it prints to stderr
is in red ?如何装饰 function 使其打印到
stdout
的任何内容为绿色,打印到stderr
的任何内容为红色? I have the termcolor
module available.我有可用的
termcolor
模块。
Bonus karma : How can I pass arguments to the decorator to specify the colours, defaulting them to red and green?额外的业力:如何将 arguments 传递给装饰器以指定颜色,默认为红色和绿色?
An interesting question.一个有趣的问题。 The simplest solution would be similar to what Pete suggest.
最简单的解决方案类似于 Pete 的建议。 Just print the escape codes before running the function to each of stderr and stdout.
只需在运行 function 到每个标准错误和标准输出之前打印转义码。 However, if both stderr and stdout feed the same terminal, as is usually the case, they will interfere.
但是,如果 stderr 和 stdout 都输入同一个终端,通常情况下,它们会干扰。
So, an alternative solution is to monkey-patch stdout and stderr with a tiny wrapper that enables the color for the duration of each write, taking care to do this only if we're in a terminal (and not piped).因此,另一种解决方案是使用一个微型包装器对标准输出和标准错误进行猴子补丁,该包装器在每次写入期间启用颜色,仅当我们在终端中(而不是管道)时才注意这样做。
#!/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()
This can still be polished a bit, but it should do the job in most cases and cleans up after itself properly.这仍然可以稍微完善一下,但在大多数情况下它应该可以完成这项工作,并且可以自行清理。 Of course, keep in mind I'm using shell-specific escape codes.
当然,请记住我使用的是特定于 shell 的转义码。 If you want portability, you'll have to replace the escape code writes with calls to a portable terminal control module.
如果您想要可移植性,则必须将转义代码写入替换为对便携式终端控制模块的调用。
Here is my code with termcolor module:这是我使用 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)
This works for me in Bash in my Mac's Terminal.app这适用于我 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.