如何使用 ast 列出函数的参数? [英] How do I list a function's parameters using ast?

查看:30
本文介绍了如何使用 ast 列出函数的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

good_file = (file for file in os.listdir() if file[-3:] == '.py' and file != '__init__.py')功能 = []对于 good_file 中的文件:with open(file, 'r') as f:模块 = ast.parse(f.read())对于 module.body 中的节点:如果 isinstance(node, ast.FunctionDef):entry = {"docs": ast.get_docstring(node), "fn_name": node.name, "params": ???}功能.附加(条目)

我正在寻找可以用来将函数的参数填充到 dict 中的内容.谢谢!

解决方案

ast 文档的>抽象语法部分告诉您在FunctionDef节点中的何处可以找到参数定义:

<块引用>

stmt = FunctionDef(标识符名称,参数 args,stmt* 主体,expr* 装饰器_列表,expr?返回)

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

所以每个FunctionDef节点都有nameargsbodydecorator_listreturns 属性.args 属性是一个新节点,类型为 arguments,也记录在案:

<块引用>

arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,arg?kwarg, expr* 默认值)

so FunctionDef.args.args 是一个参数列表,每个参数都是一个 arg 对象,等等.

arg 记录为

<块引用>

arg = (标识符arg, expr?注解)属性(int lineno,int col_offset)

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

您可能想查看 ast.dump() 函数,它会给你一个 AST 节点的快速概览:

<预><代码>>>>source = """def foo(bar, baz=None, *args, **kwargs): pass""">>>模块 = ast.parse(source)>>>ast.dump(模块)"模块(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)])"

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

<预><代码>>>>函数 = module.body[0]>>>ast.dump(function.args)"参数(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)])">>>函数.args.args[<_ast.arg 对象在 0x109852fd0>,<_ast.arg 对象在 0x109852ef0>]>>>[a.arg for a in function.args.args]['bar', 'baz']

默认值附加到 argskw_args 序列中的姓氏(defaults 用于 argskw_defaults for kwonlyargs);附加到 argskwosnlyargs 中最后 N 个名称的 N 个默认值列表.任何通用名称(在我的示例中为 *args**kwargs)都单独列出.

I'm using the ast module to parse docstrings in a Python module to turn our docs into read the docs format. I'm using the following to get the function names and docstrings into a list of dicts which the rest of my code works well with. I'm looking for something to get the parameters of the function as well:

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)

I'm looking for what I can use to fill in the function's parameters into the dict. Thanks!

解决方案

The Abstract Grammar section of the ast documentation tells you where to find the parameter definitions in a FunctionDef node:

stmt = FunctionDef(identifier name, arguments args,
                   stmt* body, expr* decorator_list, expr? returns)

In the parameters is a sequence of type name entries; the names become attributes on the node. The types are further covered in the documentation (with several 'builtin' types listed at the top, which are reflected as Python strings and integers). Types with * after them are sequences (lists), a question mark means they can be set to None.

So each FunctionDef node has name, args, body, decorator_list and returns attributes. The args attribute is a new node, of type arguments, also documented:

arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
             arg? kwarg, expr* defaults)

so FunctionDef.args.args is a list of arguments, each an arg object, etc.

arg is documented as

arg = (identifier arg, expr? annotation)
       attributes (int lineno, int col_offset)

where identifier is a built-in type, so just a string here.

You probably want to look at the ast.dump() function, which will give you a quick overview of an AST node:

>>> 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)])"

From there you can then explore and further 'dump' information to get to the actual data you need:

>>> 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']

The defaults are attached to the last names in the args or kw_args sequences (defaults for args, kw_defaults for kwonlyargs); a list of N defaults attached to the last N names in args or kwosnlyargs. Any catch-all names (*args and **kwargs in my example) are listed separately.

这篇关于如何使用 ast 列出函数的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆