【问题标题】:Convert commented out print statements to logging calls - Python将注释掉的打印语句转换为记录调用 - Python
【发布时间】:2010-12-10 15:36:43
【问题描述】:

我现在正在开发一个框架,我想使用日志记录。但是,框架的开发者一直在使用 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()

虽然这似乎不起作用。我的正则表达式远非出色,有人可以帮忙吗?

【问题讨论】:

  • 我认为您只需要在正则表达式中使用.* 而不是*。 (如果没有那个改变,这段代码就不会为我运行。)
  • 另外,这是sedperl 中的单行代码。例如,perl -p -i.orig -e 's/#print (.*)/logging.debug(\1)/' FILE...。当您的程序只有一行并且您从不打算再次阅读它时,Perl 处于最佳状态。 ;)

标签: python regex debugging logging


【解决方案1】:

如果您想在 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('foo')  --> logging.debug(('foo'))

它还搞砸了多行打印语句:

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

解决这个问题要困难得多,需要解析 cmets 并使用比正则表达式更智能的东西,因为它不能正确处理嵌套括号。 我认为您可以使用 tokenize 以及在本质上与 reindent.py 类似的代码来做到这一点,但需要一些时间和思考才能做到这一点。

【讨论】:

  • 谢谢,这正是我想要的。
  • line=re.sub(r'(\s*)print\s*(.*)',r'\1logging.debug\2',line)
  • 我改成了那个,因为我已经有了打印功能,而且它还添加了空格。没有它,所有的 logging.debug() 调用都将在源代码的最左边结束。
【解决方案2】:

如果所有打印语句都已经包含在括号中,那么 sed 将完成这项工作:

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

【讨论】:

    【解决方案3】:

    你可以用 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 ...

    【讨论】:

    • 啊,不知道.old。非常聪明。谢谢。
    【解决方案4】:

    另一种方法是将打印语句保留在原处,并将 sys.stdout 替换为类似执行日志记录的对象的文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-06
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      相关资源
      最近更新 更多