2009-02-25 41 views
7

Tôi muốn liệt kê tất cả các chuỗi trong dự án python lớn của tôi.Tìm tất cả các chuỗi trong các tệp mã python

Hãy tưởng tượng các khả năng khác nhau để tạo ra một chuỗi trong python:

mystring = "hello world" 

mystring = ("hello " 
      "world") 

mystring = "hello " \ 
      "world" 

Tôi cần một công cụ mà kết quả đầu ra "filename, linenumber, chuỗi" cho mỗi chuỗi trong dự án của tôi. Các chuỗi được trải rộng trên nhiều dòng bằng cách sử dụng "\" hoặc "('')" sẽ được hiển thị trong một dòng.

Bất kỳ ý tưởng nào về cách thực hiện điều này?

+0

nếu bạn có ý định hành động trên thông tin: "filename, linenumber, chuỗi", sau đó thư viện lib2to3 stdlib của thể cung cấp cho bạn một số ý tưởng về cách cấu trúc lại mã Python trên quy mô lớn, đặc biệt là lib2to3/refactor.py tập tin. Bạn có thể chỉ cần viết lịch thi đấu của riêng bạn cho nó và bạn đã hoàn thành. – jfs

Trả lời

3

Nếu bạn có thể làm điều này bằng Python, tôi khuyên bạn nên bắt đầu bằng cách xem mô-đun ast (Tóm tắt cú pháp cây), và đi từ đó.

0

Gettext có thể giúp bạn. Đặt dây của bạn trong _(...) cấu trúc:

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

Sau đó chạy trong dấu nhắc shell:

pygettext test.py 

Bạn sẽ nhận được một tập tin messages.pot với thông tin mà bạn cần:

# 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

Tôi nghĩ rằng họ đang cố gắng để tìm các chuỗi để họ có thể đặt _() xung quanh họ. –

2

Bạn cũng có thể xem xét phân tích mã của mình với pygments.

Tôi không biết giải pháp khác, nhưng chắc chắn là rất đơn giản để sử dụng.

11

đề xuất của thư giãn về việc sử dụng mô-đun ast trong 2.6 là tốt nhất. (Cũng có mô-đun _ast không có giấy tờ trong 2.5.) Đây là mã ví dụ cho rằng

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) 

Vấn đề là chuỗi nhiều dòng. Nếu bạn chạy trên, bạn sẽ nhận được.

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

Bạn thấy rằng nó không báo cáo sự bắt đầu của chuỗi nhiều dòng, chỉ kết thúc. Không có giải pháp tốt cho việc sử dụng các công cụ Python dựng sẵn.

Một tùy chọn khác là bạn có thể sử dụng mô-đun 'python4ply' của mình. Đây là định nghĩa ngữ pháp cho Python cho PLY, là trình tạo trình phân tích cú pháp.Dưới đây là cách bạn có thể sử dụng nó:

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) 

Kết quả từ này là

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

Không có sự hỗ trợ cho thông tin cột. (Có một số mã nhận xét gần như hoàn toàn đã được nhận xét để hỗ trợ điều đó, nhưng nó chưa được kiểm tra đầy đủ.) Sau đó, một lần nữa, tôi thấy bạn không cần nó. Nó cũng có nghĩa là làm việc với mô-đun 'trình biên dịch' của Python, nó phức tạp hơn mô-đun AST.

Tuy nhiên, với 30-40 dòng mã, bạn nên có chính xác những gì bạn muốn.

+0

Có 30-40 dòng mã, tất nhiên, chủ yếu là mã để đi qua dự án của bạn để tìm các tệp Python của bạn. –

+0

Điều đó có vẻ rất hứa hẹn! Tôi sẽ thử đề xuất đầu tiên của bạn (tôi không cần bất kỳ thông tin cột nào). Nếu nó hoạt động như tôi hy vọng tôi sẽ gửi giải pháp cuối cùng ở đây ... – mbrochh

6

Mô-đun tokenize của Python cũng sẽ thực hiện thủ thuật.

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

Tốt đẹp! Đơn giản hơn và trực tiếp hơn so với các giải pháp dựa trên phân tích cú pháp, như giải pháp tôi đã làm. +1 –

Các vấn đề liên quan