3

I would like to find a way where the execution of Python scripts automatically write the result of the expressions in the top level, as is done in interactive mode.

For instance, if I have this script.py:

abs(3)
for x in [1,2,3]:
    print abs(x)
abs(-4)
print abs(5)

and execute python script.py, I will get

1
2 
3
5

but I would rather have

3
1
2 
3
4
5

which is what one would get executing it interactively (modulo prompts).

More or less, I would like to achieve the contrary of Disable automatic printing in Python interactive session . It seems that the code module could help me, but I got no no success with it.

Community
  • 1
  • 1
anumi
  • 3,869
  • 2
  • 22
  • 22

1 Answers1

4

Well, I'm not seriously proposing using something like this, but you could (ab)use ast processing:

# -*- coding: utf-8 -*-

import ast
import argparse

_parser = argparse.ArgumentParser()
_parser.add_argument('file')


class ExpressionPrinter(ast.NodeTransformer):

    visit_ClassDef = visit_FunctionDef = lambda self, node: node

    def visit_Expr(self, node):
        node = ast.copy_location(
            ast.Expr(
                ast.Call(ast.Name('print', ast.Load()),
                         [node.value], [], None, None)
                ),
            node
        )
        ast.fix_missing_locations(node)
        return node 


def main(args):
    with open(args.file) as source:
        tree = ast.parse(source.read(), args.file, mode='exec')

    new_tree = ExpressionPrinter().visit(tree)
    exec(compile(new_tree, args.file, mode='exec'))

if __name__ == '__main__':
    main(_parser.parse_args())

Output for your example script.py:

 % python2 printer.py test2.py 
3
1
2
3
4
5
Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127