Найти все строки в файлах кода Python - PullRequest
8 голосов
/ 25 февраля 2009

Я хотел бы перечислить все строки в моем большом проекте Python.

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

mystring = "hello world"

mystring = ("hello "
            "world")

mystring = "hello " \
           "world"

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

Есть идеи, как это можно сделать?

Ответы [ 6 ]

11 голосов
/ 25 февраля 2009

откатить предложение использовать модуль 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 'compiler', который более громоздок, чем модуль AST.

Тем не менее, с 30-40 строками кода у вас должно быть именно то, что вы хотите.

7 голосов
/ 02 марта 2009

Включенный в 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
3 голосов
/ 25 февраля 2009

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

2 голосов
/ 25 февраля 2009

Вы также можете рассмотреть возможность анализа вашего кода с pygments.

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

2 голосов
/ 25 февраля 2009

Вы спрашиваете об утилитах I18N в Python?

http://docs.python.org/library/gettext.html#internationalizing-your-programs-and-modules

Существует утилита po-utils (ранее xpot), которая может помочь с этим.

http://po -utils.progiciels-bpi.ca / README.html

0 голосов
/ 25 февраля 2009

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

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

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

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 ""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...