我正在尝试理解执行python代码的过程。假设源具有函数定义。使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='element'>New Class Will Be Added Before 20% Of This Div</div>
<div class='element'>New Class Will Be Added Before 20% Of This Div</div>
<div class='element'>New Class Will Be Added Before 20% Of This Div</div>
<div class='element'>New Class Will Be Added Before 20% Of This Div</div>
<div class='element'>New Class Will Be Added Before 20% Of This Div</div>
,我将其解析为ast,它将包含ast.parse()
节点类的实例。此节点实例不是可调用的,并且与函数对象不同。如何从这个ast创建函数对象及其所有dunder属性?
答案 0 :(得分:4)
你不能(据我所知)编译一个像FunctionDef一样的任意单个AST节点。你可以做的是将整个代码片段编译为模块,在提供的命名空间中执行,然后访问其内容,包括函数。这是一个例子:
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)
现在namespace
相当于包含给定代码的模块的__dict__
。您可以访问并调用该函数:
>>> namespace['foo']
<function foo at 0x00000000023A2B70>
>>> namespace['foo'](2, 3)
z is 9
81
请注意,如果您只想做这件事,则根本不需要使用ast
。您可以直接使用compile(tree, filename='blah', mode='exec')
编译源字符串。事实上,甚至不需要涉及compile
,因为您可以直接使用exec(txt, namespace)
执行源字符串。如果您的目标只是将最终的函数对象取出,那么您根本不需要访问内部解析和编译步骤;只需在命名空间中执行整个操作,然后从那里获取函数。
答案 1 :(得分:0)
如果函数在类下,则下面的代码会有所帮助- 导入ast
txt = """
class MyClass():
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)
val = "foo"
dict_item = namespace["MyClass"].__dict__.items()
for x,y in list(dict_item):
if val == x:
print(x)
print(y)
print(type(x))
print(type(y))