解析所有方法和类的python文件

时间:2016-11-03 16:00:24

标签: python python-2.7

我正在尝试构建一个允许用户浏览到包含python模块的文件夹的程序。选择文件夹后,它将列出该文件夹中的所有python文件以及每个模块的所有类和方法。我的问题是,如果没有打开每个文件并解析" def"我有什么方法可以做到这一点。或"班级"?我注意到有一个名为mro的函数,它返回一个类的属性,但这需要我通过导入访问该类。那么有什么方法可以得到相同的结果?提前谢谢!

5 个答案:

答案 0 :(得分:1)

这是我使用AST模块提出的,它正是我所寻找的。

def fillClassList(file):
    classList = []
    className = None
    mehotdName = None
    fileName = "C:\Transcriber\Framework\ctetest\RegressionTest\GeneralTest\\" + file
    fileObject = open(fileName,"r")
    text = fileObject.read()
    p = ast.parse(text)
    node = ast.NodeVisitor()
    for node in ast.walk(p):
        if isinstance(node, ast.FunctionDef) or isinstance(node, ast.ClassDef):
            if isinstance(node, ast.ClassDef):
                className = node.name
            else:
                methodName = node.name
            if className != None and methodName != None:
                subList = (methodName , className)
                classList.append(subList)
    return classList

答案 1 :(得分:0)

如果你想知道文件的内容,那么就无法查看文件:)

您的选择取决于您是想自己解析感兴趣的内容,还是想让Python加载文件,然后询问它找到了什么。

对于一个非常简单的Python文件,如下面的testme.py,你可以做类似的事情(警告:不适合胃部不好的人):

testme.py:

class Foo (object):
    pass

def bar():
    pass 

analyze.py:

import os.path

files = ['testme.py']
for f in files: 
    print f
    modname = os.path.splitext(f)[0]
    exec('import ' + modname)
    mod = eval(modname)
    for symbol in dir(mod):
        if symbol.startswith('__'):
            continue
        print '   ', symbol, type(eval(modname + '.' + symbol))

输出:

testme.py
   Foo <type 'type'>
   bar <type 'function'>

然而,当你扩展它以处理嵌套的包和模块以及破坏代码时,它会开始变得非常糟糕,等等等等等等。对grep和/或class来说def可能更容易,并从那里开始。

玩得开心!我:心脏:元编程

答案 2 :(得分:0)

大多数Python的实现(包括解析器)都可以在stdlib中使用,因此通过仔细阅读modules index,您应该找到所需的内容。我想到的第一个模块/包是importlibinspectast,但肯定还有其他感兴趣的模块。

答案 3 :(得分:0)

我必须在我的一个模块中替换大量代码,这是我获取类和方法的方法:

def listClass(file):

    with open(file,"r") as f:
        p = ast.parse(f.read())

    # get all classes from the given python file.
    classes = [c for c in ast.walk(p) if isinstance(c,ast.ClassDef)]

    out = dict()
    for x in classes:
        out[x.name] = [fun.name for fun in ast.walk(x) if isinstance(fun,ast.FunctionDef)]

    return out

示例pprint输出:

{'Alert': ['__init__',
           'fg',
           'fg',
           'bg',
           'bg',
           'paintEvent',
           'drawBG',
           'drawAlert'],
 'AlertMouse': ['__init__', 'paintEvent', 'mouseMoveEvent'],
 'AlertPopup': ['__init__', 'mousePressEvent', 'keyPressEvent', 'systemInfo']}

答案 4 :(得分:0)

谢谢,对于这个第一次ast用户的有用示例。上面的代码带有导入,打印输出,并且没有1个拼写错误;-)

import ast

classList = []
className = None
methodName = None
fileName = "C:\\fullPathToAPythonFile.py"
fileObject = open(fileName ,"r")
text = fileObject.read()
p = ast.parse(text)
node = ast.NodeVisitor()
for node in ast.walk(p):
    if isinstance(node, ast.FunctionDef) or isinstance(node, ast.ClassDef):
        if isinstance(node, ast.ClassDef):
            className = node.name
        else:
            methodName = node.name
        if className != None and methodName != None:
            subList = (methodName , className)
            classList.append(subList)
            print("class: " + className + ", method: " + methodName)