如何从 ast.FunctionDef 节点创建函数对象? [英] How to create a function object from an ast.FunctionDef node?

查看:25
本文介绍了如何从 ast.FunctionDef 节点创建函数对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解执行 python 代码的过程.假设源有一个函数定义.使用 ast.parse(),我将其解析为一个 ast,其中将包含一个 FunctionDef 节点类的实例.此节点实例不是可调用的,并且与函数对象不同.如何从这个 ast 创建函数对象及其所有的 dunder 属性?

解决方案

您不能(据我所知)像 FunctionDef 那样编译任意的单个 AST 节点.您可以做的是将整个代码片段编译为一个模块,在提供的命名空间中执行它,然后访问其内容,包括函数.举个例子:

导入 asttxt = """def foo(x, y=2):z = x*y + 3打印(z是",z)返回 z**2"""树 = ast.parse(txt, mode='exec')代码 = 编译(树,文件名 =废话",模式 =执行")命名空间 = {}exec(代码,命名空间)

现在 namespace 相当于包含给定代码的模块的 __dict__.您可以访问和调用该函数:

<预><代码>>>>命名空间['foo']<函数 foo 在 0x00000000023A2B70>>>>命名空间['foo'](2, 3)z 是 981

请注意,如果这就是您想要做的全部,则根本不需要使用 ast.您可以直接使用 compile(tree, filename='blah', mode='exec') 编译源字符串.实际上甚至不需要涉及compile,因为您可以直接使用exec(txt, namespace) 执行源字符串.如果您的目标只是获取最终的函数对象,那么您实际上不需要访问内部解析和编译步骤;只需在命名空间中执行整个操作,然后从那里获取函数.

I am trying to understand the process by which python code gets executed. Suppose the source has a function definition. Using ast.parse(), I parse it into an ast, which will contain an instance of the FunctionDef node class. This node instance is not a callable and is not the same as the function object. How can the function object, with all its dunder attributes, be created from this ast?

解决方案

You can't (as far as I know) compile an arbitrary individual AST node like a FunctionDef. What you can do is compile the entire code snippet as a module, exec it in a provided namespace, and then access its contents, including the function. Here's an example:

import ast

txt = """
def foo(x, y=2):
    z = x*y + 3
    print("z is", z)
    return z**2
"""

tree = ast.parse(txt, mode='exec')
code = compile(tree, filename='blah', mode='exec')
namespace = {}
exec(code, namespace)

Now namespace is the equivalent of the __dict__ of a module containing the given code. You can access and call the function:

>>> namespace['foo']
<function foo at 0x00000000023A2B70>
>>> namespace['foo'](2, 3)
z is 9
81

Note that if this is all you want to do, there's no need to use ast at all. You can just compile the source string directly with compile(tree, filename='blah', mode='exec'). And in fact there's no need to even involve compile, since you can just exec the source string directly with exec(txt, namespace). If your goal is just to get the final function object out, you don't really need access to the internal parse and compile steps; just exec the whole thing in a namespace and then grab the function from there.

这篇关于如何从 ast.FunctionDef 节点创建函数对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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