如何从 ast.FunctionDef 节点创建函数对象? [英] How to create a function object from an ast.FunctionDef node?
问题描述
我试图了解执行 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')命名空间 = {}exec(代码,命名空间)
现在 namespace
相当于包含给定代码的模块的 __dict__
.您可以访问和调用该函数:
请注意,如果这就是您想要做的全部,则根本不需要使用 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屋!