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.
print
in your example function? –
Trevethick print
a bit more informative so the connection is more clear. –
Thermomotor In case the function is under a class, below code will help - import 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))
© 2022 - 2024 — McMap. All rights reserved.
ast
module documentation: "An abstract syntax tree can be compiled into a Python code object using the built-incompile()
function." – Laaspereexec()
to create the actual function object. – Trevethick