我想在我的大型python项目中列出所有字符串。
想象一下在python中创建字符串的不同可能性:
mystring = "hello world"
mystring = ("hello "
"world")
mystring = "hello " \
"world"
我需要一个工具,为我项目中的每个字符串输出“filename,linenumber,string”。使用“\”或“('')”分布在多行上的字符串应显示在一行中。
任何想法如何做到这一点?
答案 0 :(得分:11)
展开在2.6中使用ast模块的建议是一个很好的建议。 (2.5中也有未记录的_ast模块。)这是
的示例代码code = """a = 'blah'
b = '''multi
line
string'''
c = u"spam"
"""
import ast
root = ast.parse(code)
class ShowStrings(ast.NodeVisitor):
def visit_Str(self, node):
print "string at", node.lineno, node.col_offset, repr(node.s)
show_strings = ShowStrings()
show_strings.visit(root)
问题是多行字符串。如果你运行上述内容,你就会得到。
string at 1 4 'blah'
string at 4 -1 'multi\nline\nstring'
string at 5 4 u'spam'
您会看到它不报告多行字符串的开头,只报告结束字符串。使用内置的Python工具没有很好的解决方案。
另一个选择是您可以使用我的“python4ply”模块。这是PLY的Python的语法定义,它是一个解析器生成器。以下是您可以使用它的方法:
import compiler
import compiler.visitor
# from python4ply; requires the ply parser generator
import python_yacc
code = """a = 'blah'
b = '''multi
line
string'''
c = u"spam"
d = 1
"""
tree = python_yacc.parse(code, "<string>")
#print tree
class ShowStrings(compiler.visitor.ASTVisitor):
def visitConst(self, node):
if isinstance(node.value, basestring):
print "string at", node.lineno, repr(node.value)
visitor = ShowStrings()
compiler.walk(tree, visitor)
此输出是
string at 1 'blah'
string at 2 'multi\nline\nstring'
string at 5 u'spam'
不支持列信息。 (有一些主要是完整的注释代码来支持它,但它没有经过全面测试。)然后,我再次看到你不需要它。它还意味着使用Python的'编译器'模块,它比AST模块更笨拙。
尽管如此,使用30-40行代码,你应该拥有你想要的代码。
答案 1 :(得分:7)
Python包含的tokenize
模块也可以解决问题。
from __future__ import with_statement
import sys
import tokenize
for filename in sys.argv[1:]:
with open(filename) as f:
for toktype, tokstr, (lineno, _), _, _ in tokenize.generate_tokens(f.readline):
if toktype == tokenize.STRING:
strrepr = repr(eval(tokstr))
print filename, lineno, strrepr
答案 2 :(得分:3)
如果您可以在Python中执行此操作,我建议首先查看ast(抽象语法树)模块,然后从那里开始。
答案 3 :(得分:2)
您是否在询问Python中的I18N实用程序?
http://docs.python.org/library/gettext.html#internationalizing-your-programs-and-modules
有一个名为po-utils(以前称为xpot)的实用程序可以帮助解决这个问题。
答案 4 :(得分:2)
您也可以考虑使用解析代码 pygments.
我不知道其他解决方案,但确实非常 简单易用。
答案 5 :(得分:0)
Gettext可能会对您有所帮助。将您的字符串放在_(
... )
结构中:
a = _('Test')
b = a
c = _('Another text')
然后在shell提示符下运行:
pygettext test.py
您将获得包含所需信息的messages.pot
文件:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2009-02-25 08:48+BRT\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: teste.py:1
msgid "Test"
msgstr ""
#: teste.py:3
msgid "Another text"
msgstr ""