5 Amazing Python AST Module Examples

Python is one of the most powerful general-purpose programming language. Its simple syntax is easy to learn and execute. However, have you ever thought about how things work in Python? How does the interpreter run the code or execute them? How are codes interpreted by the system to produce desired results? Or, Who does all this for us? This article will discuss how things work in Python and a quick overview of them using Python ast. So, let’s start.

What is AST?

AST, also known as Abstract Syntax Tree, is a python tool that is used to directly interact with python code and modify them. How??, right. So, to understand that, we first need to see how things work when we run our code. Let’s see that. Before producing the output, it goes through a series of steps, i.e.

  • Step1: The code we have written is converted into group of chunks known as tokens. These tokens are created by the predefined instructions.
  • Step2: These tokens are then arranged in the form of a tree known as AST. AST is th tree like structure in which tokens are arranged according to the Abstarct Grammar. The order of arrangements give meaning to the tree.
  • Step3: Then the tree is converted into binary code. This gives the ease of understanding the code to the machine.
  • Step4: When interpreter gets the instructtion in the form of byte code it runs those code and make system calls from the kernel and execute the program.
  • Step5: It then return the output.

So, I hope this specifies the importance of AST and helps you understand the meaning of AST.

AST Module

So, Python has an inbuilt AST module that helps visualize processing at the backend, i.e., Abstract Syntax Grammar. The parse() function from the module is used to generate an abstract syntax tree for the code. To understand its structure, let’s see some of the code.

Example 1: Visualizing an AST for String

import ast  

# Creating AST  
code = ast.parse("print('Welcome To PythonPool')")  
print(code)  
# Printing AST
print(ast.dump(code))
# Executing AST
exec(compile(code, filename="", mode="exec"))

Output:

<_ast.Module object at 0x7f126e22a050>
Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='Welcome To PythonPool')], keywords=[]))])
Welcome To PythonPool

Explanation

So, in the above example, we first created an AST for printing the string. After that, we printed the AST using the dump() function, which shows how the tree visualizes with much more information. Then we called compile() method and exec() method to execute the AST. From the output of the dump() method, we can clearly see how our code is distributed into different components before the actual execution.

The dump() method is used to get a formatted string of the tree. It returns the formatted string, which contains information about the fields and values for the tree. This generally helps debug and get the idea of the distribution of components on the tree.

Example 2: Visualizing AST for a List

So, in the above example, we have seen how a string is interpreted by the parse() function. In this example, we will see how a List is interpreted by the AST.

import ast  

# Creating AST
code = ast.parse("print([1,2,3,4,5])")  
# Printing AST
print(ast.dump(code))
# Executing AST
exec(compile(code, filename="", mode="exec"))

Output:

Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[List(elts=[Num(n=1), Num(n=2), Num(n=3), Num(n=4), Num(n=5)], ctx=Load())], keywords=[]))])
[1, 2, 3, 4, 5]

Example 3: Visualizing Arithmetic Operations on Python AST

So, in the above two examples, we have seen how datatypes are handled by AST. Now, let’s take an example to understand how an expression is evaluated by python AST.

import ast  

# Creating AST
code = ast.parse("print(10+12)")  
# Printing AST
print(ast.dump(code))
# Executing AST
exec(compile(code, filename="", mode="exec"))

Output:

Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[BinOp(left=Num(n=10), op=Add(), right=Num(n=12))], keywords=[]))])
22

Explanation

So, in the above example, we can see that expression trees tell that we have to perform the Add() operation on two numbers that are saved in binary form and then show the output.

Example 4: Handling Multi-Operations in Python AST

So, till now, we have seen how a single component is distributed in AST. This example will show what happens if we specify more than one operation and how it is handled and distributed in AST. Let’s see.

import ast  
  
tree_ast = ast.parse('''  
location = ['Agra', 'UP']  
name = 'Taj Mahal'  

print('{} is located in {},{}'.format(name, location[0],location[1]))  
''')  
  
print(ast.dump(tree_ast))

exec(compile(tree_ast, filename="", mode="exec"))

Output:

Module(body=[Assign(targets=[Name(id='location', ctx=Store())], value=List(elts=[Str(s='Agra'), Str(s='UP')], ctx=Load())), Assign(targets=[Name(id='name', ctx=Store())], value=Str(s='Taj Mahal')), Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Call(func=Attribute(value=Str(s='{} is located in {},{}'), attr='format', ctx=Load()), args=[Name(id='name', ctx=Load()), Subscript(value=Name(id='location', ctx=Load()), slice=Index(value=Num(n=0)), ctx=Load()), Subscript(value=Name(id='location', ctx=Load()), slice=Index(value=Num(n=1)), ctx=Load())], keywords=[])], keywords=[]))])
Taj Mahal is located in Agra,UP

Explanation

So, here you can see how the assignment operation is distributed in the tree, and then more than one component is distributed in the tree, taking different nodes.

Example 5: Comments in Python AST

import ast  

# Creating AST  
code = ast.parse("# This is a comment")  
print(code)  
# Printing AST
print(ast.dump(code))
# Executing AST
exec(compile(code, filename="", mode="exec"))

Output:

<_ast.Module object at 0x7f569e710650>
Module(body=[])

Explanation

So, as the above example shows, that body node contains nothing. It means that there is no subsequent node for that, and hence it is empty. The reason for that is ast the module doesn’t include comments.

FAQs on Python AST

Q1)  Is there a python library (or package) to convert ast to java code?

No, there is no such python library that will convert ast to java code.

Q2) How do I recursively simplify a mathematical expression with ast in python 3?

You can define your evaluator class. An example is given below.

import ast

class EvaluateExpression(ast.NodeTransformer):

    # Defining operations for operators
    ops = {
        ast.Add: '+',
        ast.Sub: '-',
        ast.Mult: '*',
        ast.Div: '/',
    }

    def visit_BinOp(self, node):
        self.generic_visit(node)
        if isinstance(node.left, ast.Num) and isinstance(node.right, ast.Num):
            value = eval(f'{node.left.n} {self.ops[type(node.op)]} {node.right.n}')
            return ast.Num(n=value)
        return node

tree = ast.parse('3+2+7+8')
tree = ast.fix_missing_locations(EvaluateExpression().visit(tree))
print(ast.dump(tree))

Q3) Is there any way to round trip a python ast through XML?

You can use the RedBaron library to take inspiration for converting Python ast to XML.

Conclusion

So, today in this article, we have seen an AST and how it is created. Then we discussed the AST module provided by Python and how it helps in building the Syntax tree for our code. Then we tried visualizing the tree in different scenarios and different operations. This gave us an understanding of how a code actually works. I hope this article has helped you. Thank You.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments