问题
first of all, thank you for your help in forward. I'm using Python and I'm trying to search a .py file for all of its functions starting with the name "test_" and all of the variables included. The variables I search for are formatted like this: "var["blabla"]". So here I have an example:
def test_123:
init = var["blabla1"]
init2 = var["blabla2"]
*somecode*
def test_456:
init3 = var["blabla3"]
init4 = var["blabla4"]
*somecode*
What I already wrote is a script, that returns all my functions and variables in a html file. But I have to get them sorted, so I can work with them better.
Right now its like this:
test_123,test456
var["blabla1"],var["blabla2"],...
And I want it like this:
test_123:
var["blabla1"]
var["blabla2"]
test_456:
var["blabla3"]
var["blabla4"]
EDIT: I have this right now:
def suchentpar():
fobj = open("2.py", "r")
search = fobj.read()
tpar = re.findall(r'var\[\"\w+\"\]',search)
return tpar
fobj.close()
def suchenseq():
fobj = open("2.py", "r")
search = fobj.read()
seq = re.findall(r'test\_\w+',search)
return seq
fobj.close()
回答1:
First off, your code as is will never run fobj.close()
, given that the functions will exit via return
the line above...
Then, a way to obtain what you want could be:
import re
fcontent = '''
def test_a(self):
var["hello"]
var["world"]
def test_b(self):
var["hola"]
var["mundo"]
'''
dict_ = {}
chunks = [chunk for chunk in fcontent.split('def ') if chunk.strip()]
for chunk in chunks:
tname = re.findall(r'test\_\w+', chunk)[0]
vars = re.findall(r'var\[\"\w+\"\]', chunk)
dict_[tname] = vars
for k, v in dict_.items():
print k
for e in v:
print "\t%s" % e
NOTE: In the above code I left the regexes as you wrote them, but of course you could improve on them, and could change the first re.findall
in re.search
if you wished. In other words: what above is purely a demo to show the concept, but you should work on the edge cases and efficiency...
HTH!
回答2:
This program will help you with the first part of your question, namely finding all functions that start with test_
. You might expand it to find variable definitions of your choice as well, but this is a little more complicated.
The basic idea is to use the ast
package to parse your Python source, and scan the result for function definitions. Thus, you won't detect false positives, for example a function definition inside of a string or comment. Example:
# define strings for function test_foobar().
foobar="def test_foobar(): pass"
This input contains two bad matches and would be detected by using regular expressions, if not very carefully crafted. Using ast
, this is much simpler than you may think. Working example:
#!/usr/bin/env python
import ast
import sys
def test_foobar():
pass
class FunctionNameFinder(ast.NodeVisitor):
def visit_FunctionDef(self, node):
if node.name.startswith("test_"):
print node.name, "on line", node.lineno
with open(sys.argv[1], 'rU') as f:
FunctionNameFinder().visit(ast.parse("".join(f.readlines())))
This program can be run on itself to detect the dummy function on line 6!
EDIT: The following extension will detect some variable assignments, but not all. Just to point out the direction.
def visit_FunctionDef(self, node):
if node.name.startswith("test_"):
print node.name, "on line", node.lineno
self.generic_visit(node)
def visit_Subscript(self, node):
if isinstance(node.value, ast.Name) and \
isinstance(node.slice, ast.Index):
if isinstance(node.slice.value, ast.Str):
print '%s["%s"] on line %s' % (
str(node.value.id),
str(node.slice.value.s),
node.lineno)
elif isinstance(node.slice.value, ast.Num):
print '%s[%s] on line %s' % (
str(node.value.id),
str(node.slice.value.n),
node.lineno)
HTH.
回答3:
Elaborating on previous answers, you can also use an OrderedDict (python 2.7+), to maintain the ordering.
import re
from collections import OrderedDict
fcontent = '''
def test_a(self):
var["hello"]
var["world"]
def test_b(self):
var["hola"]
var["mundo"]
'''
dict_ = OrderedDict()
chunks = [chunk for chunk in fcontent.split('def') if chunk.strip()]
for chunk in chunks:
print chunk
tname = re.findall(r'test\_\w+', chunk)[0]
vars = re.findall(r'var\[\"\w+\"\]', chunk)
dict_[tname] = vars
print dict_
L.
来源:https://stackoverflow.com/questions/8254266/find-specific-variables-inside-a-function-and-return-them-sorted