将已注释掉的print语句转换为日志记录调用 - Python

时间:2010-12-10 15:36:43

标签: python regex debugging logging

我现在正在攻击框架,我想使用日志记录。但是,框架的开发人员一直在使用print语句进行调试,并且它们都已针对生产版本进行了注释。我想知道,有没有人知道找到这些的正则表达式,并将它们转换为日志记录调用。

这是我到目前为止的想法:

import re
import sys
import StringIO

if not len(sys.argv) != 2:
    print 'Syntax: printtologging.py file_to_process'

regex = r'#print (?P<debugstring>*)$'

output = StringIO.StringIO('w+')

def replace(match_object):
    return 'logging.debug({0})'.format(match_object.group_dict['debugstring'])

with open(sys.argv[1]) as f:
    output.writelines([re.sub(regex, replace, line) for line in f.readlines()])

output.seek(0)
print output.read()

虽然这似乎不起作用。我的正则表达式远非辉煌,任何人都可以帮忙吗?

4 个答案:

答案 0 :(得分:3)

如果您想在Python中执行此操作,请考虑使用fileinput模块:

import fileinput
import sys
import re

def convert(paths):
    for line in fileinput.input(paths, inplace=True, backup='~'):
        line=re.sub(r'#\s*print\s*(.*)',r'logging.debug(\1)',line)
        sys.stdout.write(line)

if __name__=='__main__':
    convert(sys.argv[1:])

你可以这样调用脚本

% print2log.py *.py

它会就地转换脚本,并生成一个以~结尾的备份文件。

请注意,正则表达式转换

#print 'foo'   -->  logging.debug('foo')

但如果print语句已经有一个括号,则添加一组额外的括号:

#print('foo')  --> logging.debug(('foo'))

它还搞砸了多行打印声明:

#print('''foo        logging.debug(('''foo)
#bar''')       -->   #bar''')

修复这是一个更难的问题,需要解析注释并使用比正则表达更智能的东西,正则表达式无法正确处理嵌套括号。 我认为您可以使用tokenize进行此操作,并且代码与reindent.py的精神相似,但需要花费一些时间并考虑做到正确。

答案 1 :(得分:1)

如果括号中已包含所有打印语句,则sed将完成此任务:

sed -i s/#print/logging\.debug/g files_to_process

答案 2 :(得分:1)

你可以用sed实现相同的目标

sed -i.old -E -e "s/#+[[:space:]]*print (.*)/logging.debug(\1)/" FILE

我让你的正则表达式更强大了。如果#和print之间存在多个#和/或空格,它现在也匹配。

请注意,它仍然无法处理某些边缘情况,例如

#print 'foo'; print'bar'

-i.old使用写入FILE.old的备份激活就地编辑。如果您不想要备份,请忽略.old,即sed -i -E ...

答案 3 :(得分:0)

另一种方法是保留print语句,并将sys.stdout替换为执行日志记录的对象等文件。