Find specific variables inside a function and return them sorted

亡梦爱人 提交于 2020-01-14 19:17:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!