Search code examples
pythontext-filesediting

Modify python file as if it were a text file, but still having variables and such


I am testing some python stuff, and i started wondering if it was possible to modify a python file as if it were a text file.

I have looked at the open(<filename>, "r+"), but this just edits the file. I can't modify it like it was a python script, modifying the actual script and not just the cache.


#main.py

import filea

filea.var1edit("Hello world")

Expected before:

#filea.py

var1 = "Text"
def var1edit(var):
  global var1
  var1 = var

Expected after:

#filea.py

var1 = "Hello world"
def var1edit(var):
  global var1
  var1 = var

Actual after:

#filea.py

var1 = "Text"
def var1edit(var):
  global var1
  var1 = var

Solution

  • Module ast and astunparse can be useful. We first read the .py file, generate the AST, modify the AST, unparse it and write the new code back. Here is an example:

    #main.py
    import ast
    import astunparse
    
    class ReWriteSource(ast.NodeTransformer):
        #visit 'Assign' node and modify
        def visit_Assign(self,node):
            if node.targets[0].id == 'var1' and isinstance(node.value,ast.Str):
                node.value.s = 'Hello World!'
            return node
    
    #read .py file
    with open('filea.py','r') as f:
        source = f.read()
    #generate the AST
    source_ast = ast.parse(source)
    #modify the AST
    ReWriteSource().visit(source_ast)
    #unparse and write it back
    with open('filea.py','w') as f:
        f.write(astunparse.unparse(source_ast))
    

    original filea.py:

    #filea.py
    var1 = 'Text'
    def var1edit(var):
        global var1
        var1 = var
    

    modified filea.py:

    #filea.py
    var1 = 'Hello World!'
    def var1edit(var):
        global var1
        var1 = var