在函数内查找特定变量并将它们返回排序

时间:2011-11-24 08:49:03

标签: python function sorting variables

首先,感谢您的帮助。 我正在使用Python,我正在尝试搜索.py文件中的所有函数,以名称“test_”开头,并包含所有变量。我搜索的变量的格式如下:“var [”blabla“]”。所以这里有一个例子:

def test_123:

    init = var["blabla1"]
    init2 = var["blabla2"]
    *somecode*

def test_456:

    init3 = var["blabla3"]
    init4 = var["blabla4"]
    *somecode*

我已编写的是一个脚本,它将所有函数和变量返回到html文件中。但是我必须对它们进行排序,这样我才能更好地与它们合作。

现在它是这样的:

test_123,test456
var["blabla1"],var["blabla2"],...

我想要这样:

test_123:

var["blabla1"]
var["blabla2"]

test_456:

var["blabla3"]
var["blabla4"]

编辑:我现在有这个:

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()

3 个答案:

答案 0 :(得分:1)

此程序将帮助您解决问题的第一部分,即查找以test_ 开头的所有功能。你可以扩展它以找到你选择的变量定义,但这有点复杂。

基本思想是使用ast包来解析Python源代码,并扫描结果以获取函数定义。因此,您不会检测误报,例如字符串或注释中的函数定义。例如:

# define strings for function test_foobar().
foobar="def test_foobar(): pass"

此输入包含两个不匹配,如果不是非常精心设计,则可以使用正则表达式进行检测。使用ast,这比您想象的要简单得多。工作示例:

#!/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())))

该程序可以自行运行,以检测第6行的虚拟功能!

编辑:以下扩展程序将检测某些变量分配,但不是全部。只是指出方向。

        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。

答案 1 :(得分:0)

首先,您的代码将永远不会运行fobj.close(),因为这些函数将通过return上面的行退出...

然后,获得你想要的东西的方法可能是:

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

注意:在上面的代码中,我在编写时留下了正则表达式,但当然您可以改进它们,并可以更改re.findall中的第一个re.search如果你愿意的话换句话说:以上只是一个展示概念的演示,但你应该研究边缘案例和效率...

HTH!

答案 2 :(得分:0)

在阐述之前的答案时,您还可以使用OrderedDict(python 2.7+)来维护排序。

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,