我有以下用于着色屏幕消息的功能:
def error(string):
return '\033[31;1m' + string + '\033[0m'
def standout(string):
return '\033[34;1m' + string + '\033[0m'
我按如下方式使用它们:
print error('There was a problem with the program')
print "This is normal " + standout("and this stands out")
我希望将输出记录到一个文件(除STDOUT之外)没有ANSI颜色代码,希望无需在每个print
语句中添加第二个“记录”行。
原因是如果您只是python program.py > out
,那么文件out
将具有ANSI颜色代码,如果您在纯文本编辑器中打开,这看起来很糟糕。
有什么建议吗?
答案 0 :(得分:10)
sys.stdout.isatty
功能可能会有所帮助:
from sys import stdout
def error(string, is_tty=stdout.isatty()):
return ('\033[31;1m' + string + '\033[0m') if is_tty else string
def standout(string, is_tty=stdout.isatty()):
return ('\033[34;1m' + string + '\033[0m') if is_tty else string
这实际上是我能想到的少数用法之一,使用未设置为None
的默认参数,因为默认参数是在编译时在Python中而不是像在C ++中那样在运行时评估的...
如果你真的需要,也可以显式覆盖行为,虽然这不会让你在重定向时操纵stdout本身。您有没有理由不使用logging
模块(也许您不知道它)?
答案 1 :(得分:6)
如果您希望打印到终端和日志文件,那么我建议使用日志记录模块。您甚至可以定义自定义格式化程序,因此记录到该文件可以清除终端代码:
import optparse
import logging
def error(string):
return '\033[31;1m' + string + '\033[0m'
def standout(string):
return '\033[34;1m' + string + '\033[0m'
def plain(string):
return string.replace('\033[34;1m','').replace('\033[31;1m','').replace('\033[0m','')
if __name__=='__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(message)s',
filemode='w')
logger=logging.getLogger(__name__)
def parse_options():
usage = 'usage: %prog [Options]'
parser = optparse.OptionParser()
parser.add_option('-l', '--logfile', dest='logfile',
help='use log file')
opt,args = parser.parse_args()
return opt,args
opt,args=parse_options()
if opt.logfile:
class MyFormatter(logging.Formatter):
def format(self,record):
return plain(record.msg)
fh = logging.FileHandler(opt.logfile)
fh.setLevel(logging.INFO)
formatter = MyFormatter('%(message)s')
fh.setFormatter(formatter)
logging.getLogger('').addHandler(fh)
logger.info(error('There was a problem with the program'))
logger.info("This is normal " + standout("and this stands out"))
test.py
仅打印到终端。
test.py -l test.out
打印到终端和文件test.out
。
在所有情况下,终端的文本都有颜色代码,而日志记录没有。
答案 2 :(得分:1)
unubtu下面的答案很棒,但我认为MyFormatter需要稍作修改才能在format()方法中强制执行格式化
fd