Python是否允许解析模块并返回其中的所有函数/类?

时间:2015-06-11 18:58:38

标签: python

我很好奇,除了将py文件解析为文本文件之外,还有一种方法可以检索模块中实际存在的内容。

例如;如果我导入一个模块,并想知道模块包含什么,它的用法(需要的参数,返回类型等),有没有办法直接通过Python,或者我必须实际加载文件,如我会为一个文本文件,并手动解析它?

我有很多我想要记录的模块,这样的事情可以节省我每个模块的时间并逐个检查。

3 个答案:

答案 0 :(得分:1)

您可以使用ast来正确解析所有模块:

import inspect
import importlib
import ast


class ParseMod(ast.NodeVisitor):
    def visit_FuncDef(self,node):
        print("In func")
        print(node.name)
        print(node.args)
        self.generic_visit(node)

    def visit_ClassDef(self,node):
        print("in class")
        print(node.name)
        for n in node.body:
            print(n.name)
        self.generic_visit(node)

    def visit_Call(self, node):
        print("In call")
        print(node.func.id)
        print([ast.literal_eval(arg) for arg in node.args])
        self.generic_visit(node)


mod = "test2"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))

par = ParseMod()

par.visit(p)

输入:

class Foobar(object):
    def func(self):
        return "func"


class Bar(object):
    def func2(self):
        return  "func2"

class Foo():
    def __init__(self):
        self.x = 1
        self.y = 2
        self.z = 3
    def func_foo(self):
        return "func_foo"


def some_func(a,b):
    """
    :param a: int
    :param b: int
    :return: int
    """
    return a,b

some_func(1,2)

输出:

in class
Foobar
func
in class
Bar
func2
in class
Foo
__init__
func_foo
In call
some_func
[1, 2]

greentreesnakes文档中包含所有可用属性的完整列表以及每个属性的说明。

如果您只想收集函数和类节点:

import inspect
import importlib
import ast
mod = "test"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))



classes = [node for node in p.body if isinstance(node, ast.ClassDef)]
funcs = [node for node in p.body if isinstance(node, ast.FunctionDef)]

print(classes)
print(funcs)
[<_ast.ClassDef object at 0x7f9bc7884190>, <_ast.ClassDef object at 0x7f9bc7884350>, <_ast.ClassDef object at 0x7f9bc7884510>]    
[<_ast.FunctionDef object at 0x7f89d3377c50>]

然后从每个中提取你想要的东西:

for f in funcs:
    print(f.name)
    print([a.id for a in  f.args.args])
    print(ast.get_docstring(f))

some_func
['a', 'b']
:param a: int
:param b: int
:return: int

还有一些示例用法herehere

答案 1 :(得分:0)

您可以使用dir方法获取与模块的每个成员对应的字符串列表:

import some_module
print dir(some_module)

这将为您提供模块的所有类和功能,但有两个缺点:

  • 为您提供非类或功能的成员。例如,dir(Tkinter)包含VERTICALSUNKEN以及OFFINSERT,它们都是常规字符串。
  • 如果模块包含文件级别的任何代码,则将执行该代码。一般来说不是什么大不了的事,但如果你想要检查很多模块,那么失去的时间就会堆积起来。

答案 2 :(得分:0)

一种方法是使用inspect.getmembers()来反省模块的内容:

import types
import inspect
import mymodule

# find classes, shove them in a {'name':object} dict
is_class = lambda x: isinstance(x, type)
classes = dict(inspect.getmembers(mymodule, predicate=is_class))

# find functions, shove them in a {'name':object} dict
is_func = lambda x: isinstance(x, (types.FunctionType, types.BuiltinFunctionType))
functions = dict(inspect.getmembers(mymodule, predicate=is_func))

# etc...

听起来您正在寻找的是自动生成API文档的工具of which there are several