интересный вопрос.Самое простое решение будет похоже на то, что предлагает Пит.Просто напечатайте управляющие коды перед запуском функции для каждого из 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()
Это все еще можно немного отшлифовать, но в большинстведела и убирает за собой должным образом.Конечно, имейте в виду, что я использую специфичные для оболочки escape-коды.Если вы хотите переносимости, вам придется заменить записи escape-кода вызовами на портативный модуль управления терминалом.