How to create a function object from an ast.FunctionDef node?

后端 未结 2 1253
执笔经年
执笔经年 2021-01-19 07:44

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 as

相关标签:
2条回答
  • 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.

    0 讨论(0)
  • 2021-01-19 08:14

    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))
    
    0 讨论(0)
提交回复
热议问题