2009-02-25 5 views
7

Я хотел бы перечислить все строки в моем большом проекте python.Найти все строки в файлах кода python

Представьте себе различные возможности для создания строки в Python:

mystring = "hello world" 

mystring = ("hello " 
      "world") 

mystring = "hello " \ 
      "world" 

Мне нужен инструмент, который выводит «имя файла, номер строки, строка» для каждой строки в моем проекте. Строки, которые распределены по нескольким строкам с использованием «\» или «('')», должны отображаться в одной строке.

Любые идеи, как это можно сделать?

+0

если вы намерены действовать на информацию: «имя файла, номер строки, строки», то библиотека lib2to3 STDLIB в может дать вам некоторые идеи о том, как реорганизовать код Python в больших масштабах, особенно lib2to3/refactor.py файл. Возможно, вам просто нужно написать свой собственный прибор, и все готово. – jfs

ответ

3

Если вы можете сделать это в Python, я бы предложил начать с просмотра модуля ast (абстрактное синтаксическое дерево) и оттуда.

0

Gettext может помочь вам. Поместите ваши строки в _(...) структур:

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

Затем запустите в командной строке:

pygettext test.py 

Вы получите messages.pot файл с информацией вам необходимо:

# 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

Я думаю, что они пытаются найти строки, чтобы они могли поместить вокруг них _(). –

2

Вы также можете рассмотреть возможность разбора кода с помощью pygments.

Я не знаю другого решения, но это точно прост в использовании.

11

предложение о том, чтобы использовать модуль ast в 2.6, является хорошим. (Там же недокументированные _ast модуль 2.5.) Вот пример кода для этого

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». Это определение грамматики для Python для PLY, которое является генератором синтаксического анализатора.Вот как вы можете использовать его:

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 строками кода вы должны иметь именно то, что хотите.

+0

Эти 30-40 строк кода, конечно, в основном являются кодом для прохождения вашего проекта, чтобы найти ваши файлы Python. –

+0

Это выглядит очень перспективно! Я попробую ваше первое предложение (мне не нужна информация о столбцах). Если он работает, как я надеюсь, я отправлю окончательное решение здесь ... – mbrochh

6

Включенный в комплект 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 
+0

Ницца! Более простые и более прямые, чем решения, основанные на парсерах, как и то, что я сделал. +1 –

Смежные вопросы