Skip to content Skip to sidebar Skip to footer

Find Specific Variables Inside A Function And Return Them Sorted

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 varia

Solution 1:

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 pythonimport ast
import sys

deftest_foobar():
        passclassFunctionNameFinder(ast.NodeVisitor):
        defvisit_FunctionDef(self, node):
                if node.name.startswith("test_"):
                        print node.name, "on line", node.lineno

withopen(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.

defvisit_FunctionDef(self, node):
                if node.name.startswith("test_"):
                        print node.name, "on line", node.lineno
                self.generic_visit(node)

        defvisit_Subscript(self, node):
                ifisinstance(node.value, ast.Name) and \
                   isinstance(node.slice, ast.Index):
                        ifisinstance(node.slice.value, ast.Str):
                                print'%s["%s"] on line %s' % (
                                        str(node.value.id),
                                        str(node.slice.value.s),
                                        node.lineno)
                        elifisinstance(node.slice.value, ast.Num):
                                print'%s[%s] on line %s' % (
                                        str(node.value.id),
                                        str(node.slice.value.n),
                                        node.lineno)

HTH.

Solution 2:

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] = varsfor 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!

Solution 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] = varsprint dict_

L.

Post a Comment for "Find Specific Variables Inside A Function And Return Them Sorted"