如何使用ast列出函数的参数?

tig*_*rae 0 python abstract-syntax-tree

我正在使用ast模块来解析Python模块中的文档字符串,以将我们的文档转换为docs格式.我正在使用以下内容将函数名称和文档字符串放入我的其余代码可以很好地使用的dicts列表中.我正在寻找能够获得函数参数的东西:

good_file = (file for file in os.listdir() if file[-3:] == '.py' and file != '__init__.py')

functions = []

for file in good_file:
     with open(file, 'r') as f:
         module = ast.parse(f.read())

     for node in module.body:
         if isinstance(node, ast.FunctionDef):
         entry = {"docs": ast.get_docstring(node), "fn_name": node.name, "params": ???}

         functions.append(entry)
Run Code Online (Sandbox Code Playgroud)

我正在寻找可以用来将函数的参数填入dict的东西.谢谢!

Mar*_*ers 8

文档Abstract Grammar部分ast告诉您在哪个FunctionDef节点中找到参数定义:

stmt = FunctionDef(identifier name, arguments args,
                   stmt* body, expr* decorator_list, expr? returns)
Run Code Online (Sandbox Code Playgroud)

在参数中是一系列type name条目; 名称成为节点上的属性.这些类型在文档中进一步介绍(顶部列出了几个"内置"类型,它们反映为Python字符串和整数).*其后的类型是序列(列表),问号表示可以设置为None.

因此,每个FunctionDef节点有name,args,body,decorator_listreturns属性.该args属性是一个类型的新节点arguments,也记录在案:

arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
             arg? kwarg, expr* defaults)
Run Code Online (Sandbox Code Playgroud)

FunctionDef.args.args参数列表也是如此,每个参数都是arg对象等.

arg 记录为

arg = (identifier arg, expr? annotation)
       attributes (int lineno, int col_offset)
Run Code Online (Sandbox Code Playgroud)

哪里identifier是内置类型,所以这里只是一个字符串.

您可能希望查看该ast.dump()函数,它将为您提供AST节点的快速概述:

>>> source = """def foo(bar, baz=None, *args, **kwargs): pass"""
>>> module = ast.parse(source)
>>> ast.dump(module)
"Module(body=[FunctionDef(name='foo', args=arguments(args=[arg(arg='bar', annotation=None), arg(arg='baz', annotation=None)], vararg=arg(arg='args', annotation=None), kwonlyargs=[], kw_defaults=[], kwarg=arg(arg='kwargs', annotation=None), defaults=[NameConstant(value=None)]), body=[Pass()], decorator_list=[], returns=None)])"
Run Code Online (Sandbox Code Playgroud)

然后,您可以在那里探索并进一步"转储"信息以获取所需的实际数据:

>>> function = module.body[0]
>>> ast.dump(function.args)
"arguments(args=[arg(arg='bar', annotation=None), arg(arg='baz', annotation=None)], vararg=arg(arg='args', annotation=None), kwonlyargs=[], kw_defaults=[], kwarg=arg(arg='kwargs', annotation=None), defaults=[NameConstant(value=None)])"
>>> function.args.args
[<_ast.arg object at 0x109852fd0>, <_ast.arg object at 0x109852ef0>]
>>> [a.arg for a in function.args.args]
['bar', 'baz']
Run Code Online (Sandbox Code Playgroud)

默认值附加到argskw_args序列中的姓氏(defaultsfor args,kw_defaultsfor kwonlyargs); 连接到最后N个名字以N缺省值的列表argskwosnlyargs.任何全能名称(*args以及**kwargs我的示例)都单独列出.