2009-02-25 6 views
7

Ich möchte alle Zeichenfolgen in meinem großen Python-Projekt auflisten.Finden Sie alle Zeichenfolgen in Python-Code-Dateien

die verschiedenen Möglichkeiten Stellen Sie sich eine Zeichenfolge in Python zu erstellen:

mystring = "hello world" 

mystring = ("hello " 
      "world") 

mystring = "hello " \ 
      "world" 

Ich brauche ein Tool, das "Dateiname, Zeilennummer, string" für jede Saite in meinem Projekt gibt. Strings, die mit "\" oder "('')" auf mehrere Zeilen verteilt sind, sollten in einer Zeile dargestellt werden.

Irgendwelche Ideen, wie dies getan werden könnte?

+0

, wenn Sie darauf bedacht, den Informationen zu handeln: „Dateiname, Zeilennummer, string“ dann stdlib der lib2to3 Bibliothek könnte Ihnen einige Ideen geben, wie Python-Code in großem Maßstab, Refactoring, insbesondere lib2to3/refactor.py Datei. Sie müssen vielleicht nur Ihr eigenes Gerät dafür schreiben und Sie sind fertig. – jfs

Antwort

3

Wenn Sie dies in Python tun können, würde ich vorschlagen, beginnend mit dem ast (Abstract Syntax Tree) -Modul, und von dort aus gehen.

0

Gettext könnte Ihnen helfen. Legen Sie Ihre Saiten in _(...) Strukturen:

a = _('Test') 
b = a 
c = _('Another text') 

Dann in der Shell-Prompt ausführen:

pygettext test.py 

Sie erhalten eine messages.pot Datei mit den Informationen, die Sie brauchen:

# SOME DESCRIPTIVE TITLE. 
# Copyright (C) YEAR ORGANIZATION 
# FIRST AUTHOR <[email protected]>, 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 protected]>\n" 
"Language-Team: LANGUAGE <[email protected]>\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 "" 
+0

Ich denke, dass sie versuchen, die Zeichenfolgen zu finden, damit sie die _() um sie legen können. –

2

Sie können auch in Betracht ziehen, Ihren Code mit zu analysieren

Ich weiß nicht die andere Lösung, aber es ist sicher sehr einfach zu bedienen.

11

Abwickelstation Anregung des ast Modul in 2.6 zu verwenden, ist ein guter. (Es gibt auch die undokumentierten _ast Modul in 2.5.) Hier ist Beispielcode für das

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) 

Das Problem mehrzeilige Strings ist. Wenn Sie das oben genannte ausführen, werden Sie erhalten.

string at 1 4 'blah' 
string at 4 -1 'multi\nline\nstring' 
string at 5 4 u'spam' 

Sie sehen, dass es nicht den Anfang der mehrzeiligen Zeichenfolge meldet, nur das Ende. Es gibt keine gute Lösung für das Verwenden der integrierten Python-Tools.

Eine weitere Option ist, dass Sie mein 'python4ply' Modul verwenden können. Dies ist eine Grammatikdefinition für Python für PLY, die ein Parser-Generator ist.Hier ist, wie Sie könnte es verwenden:

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) 

Die Ausgabe von dieser ist

string at 1 'blah' 
string at 2 'multi\nline\nstring' 
string at 5 u'spam' 

Es gibt keine Unterstützung für Spalteninformationen. (Es gibt einige größtenteils vollständig auskommentierten Code, um das zu unterstützen, aber es ist nicht vollständig getestet.) Andererseits, ich sehe, dass Sie es nicht brauchen. Es bedeutet auch, mit Pythons "Compiler" -Modul zu arbeiten, das unhandlicher ist als das AST-Modul.

Noch, mit einer 30-40 Zeilen Code sollten Sie genau das haben, was Sie wollen.

+0

Diese 30-40 Zeilen Code sind natürlich der Code, der das Projekt durchläuft, um Ihre Python-Dateien zu finden. –

+0

Das sieht sehr vielversprechend aus! Ich werde Ihren ersten Vorschlag versuchen (ich brauche keine Spalteninformationen). Wenn es funktioniert wie ich hoffe, werde ich hier die endgültige Lösung posten ... – mbrochh

6

Python enthalten tokenize Modul wird auch den Trick tun.

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 
+0

Schön! Einfacher und direkter als die Parser-basierten Lösungen, wie die, die ich gemacht habe. +1 –

Verwandte Themen