2012-12-18 81 views
0
#!/usr/bin/env python` 
import sys` 
import binascii` 
import string 
sample = "foo.apples" 
data_file = open("file1.py","r") 
dat_file = open("file2.txt", "w") 
for line in data_file: 
    if sample in line: 
     dat_file.writelines(line) 
dat_file.close()` 

當我這樣做時,我能夠找到字符串foo.apples。問題是foo.apples存在於python文件的各行中。我想要那些在特定函數內部的行。我需要這個def函數中的行。使用Python在python文件的模塊中搜索字符串

Example:

def start(): 
    foo.apples(a,b) 
    foo.apples(c,d) ... so on. 
+0

你的意思是'功能'嗎?在Python中,整個文件是模塊... – mgilson

+0

哦好吧,那麼我的意思是功能。像def start()函數一樣。 – Ram

+0

我編輯了這篇文章!謝謝。 – Ram

回答

0

以下程序發現def S和如果壓痕保持def內將追加樣本串到輸出文件。

import re 

sample = 'foo.apples' 
data_file = open("file1.py", "r") 
out_file = open("file2.txt", "w") 
within_def = False 
def_indent = 0 

for line in data_file: 
    def_match = re.match(r'(\s*)def\s+start\s*\(', line) # EDIT: fixed regex 
    if def_match and not within_def: 
     within_def = True 
     def_indent = len(def_match.group(1)) 
    elif within_def and re.match(r'\s{%s}\S' % def_indent, line): 
     within_def = False 

    if within_def and sample in line: 
     out_file.writelines(line) 

out_file.close() 
data_file.close() 

測試了一個例子file1.py

+0

好吧,這是所有def的返回值。所以我有另外一個def的'sample' :-( – Ram

+0

@Ram對不起,我誤解了你的問題。我編輯了答案(請參閱'#EDIT'行),以便在「def start」縮進級別內正確地查找「foo.apples」。 – mVChr

+0

太棒了!有效 :) – Ram

0

一,稍微偏離路徑的方法來,這將是使用inspect模塊的getsource方法。考慮下面的(理論)test1.py文件:

class foo(object): 
    apples = 'granny_smith' 
    @classmethod 
    def new_apples(cls): 
     cls.apples = 'macintosh' 

def start(): 
    """This is a pretty meaningless python function. 
    Attempts to run it will definitely result in an exception being thrown""" 
    print foo.apples 
    foo.apples = 3 
    [x for x in range(10)] 
    import bar as foo 

現在,你想了解的start代碼:

import inspect 
import test1 #assume it is somewhere that can be imported 

print inspect.getsource(test1.start) 

好了,現在我們只有函數的源代碼。現在,我們可以通過解析:

for line in inspect.getsource(test1.start).splitlines(): 
    if 'foo.apples' in line: 
     print line 

這裏有一些優勢 - Python做解析出的功能塊,當它導入該文件的所有工作。但缺點是文件實際上需要導入。根據您的文件來自何處,這可能會在您的程序中引入一個安全漏洞 - 您將運行(可能)「不可信」代碼。

0

這是一個非pythonic方式,未經測試,但它應該工作。

sample = "foo.apples" 
infile = open("file1.py", "r") 
outfile = open("file2.txt", "w") 
in_function = False 

for line in infile.readlines(): 
    if in_function: 
     if line[0] in(" ", "\t"): 
      if sample in line: 
       outfile.write(line) 
     else: 
      in_function = False 
    elif line.strip() == "def start():": 
     in_function = True 
infile.close() 
outfile.close() 

我建議做的這個功能,這需要sample,輸入文件,以及我們應該從它的參數搜索功能。然後它會返回包含文本的所有行的列表或元組。

def findFromFile(file, word, function): 
    in_function = False 
    matches = [] 
    infile = open(file, "r") 

    for line in infile.readlines(): 
     if in_function: 
      if line[0] in(" ", "\t"): 
       if word in line: 
        matches.append(line) 
      else: 
       in_function = False 
     elif line.strip() == "def %s():"%function: 
      in_function = True 

    infile.close() 
    return matches 
+0

嗨馬希謝謝。我想你所建議的第一個類似於狀態機的工作,我想在這裏找到關於某人提到的那個帖子。事情是,當我給def start()時它不起作用:當我昨天試圖這樣做時。我現在會再試一次。 – Ram

+0

確保你只用「start」調用,如下所示:'findFromFile(「test.txt」,「foo.apples」,「start」)' – 2012-12-19 06:34:50

相關問題