Caio S. Souza
Caio S. Souza

Reputation: 151

Python redirect return statement to stdout

I am writing a Python interpreter and want to redirect the function's return values to stdout, like the Python Interpreter in Interactive Mode. Within this mode, when the user calls a function, its return value is printed on the screen. The same occurs with expressions.

E.g.

>>> foo()
'Foo return value'
>>> 2+4
6
>>> print('Hello!')
'Hello!'

Changing the sys.stdout only affects the print function. How do I redirect the other expressions to stdout?

Thank you

Upvotes: 0

Views: 2399

Answers (2)

abarnert
abarnert

Reputation: 366073

First, the interactive mode does not print the return value from any function called. Instead, it prints the result of whatever expression the user typed in. If that's not a function call, it still gets printed. If it has 3 function calls in it, it still prints one result, not 3 lines. And so on.

So, trying to redirect function return values to stdout is the wrong thing to do.

What the interactive interpreter does is something sort of like this:

line = raw_input(sys.ps1)
_ = eval(line)
if _ is not None:
    print repr(_)

(You may notice that you can change sys.ps1 from the interactive prompt to change what the prompt looks like, access _ to get the last value, etc.)

However, that's not what it really does. And that's not how you should go about this yourself either. If you try, you'll have to deal with complexities like keeping your own globals separate from the user's, handling statements as well as expressions, handling multi-line statements and expressions (doing raw_input(sys.ps2) is easy, but how do you know when to do that?), interacting properly with readline and rlcomplete, etc.

There's a section of the documentation called Custom Python Interpreters which explains the easy way to do this:

The modules described in this chapter allow writing interfaces similar to Python’s interactive interpreter. If you want a Python interpreter that supports some special feature in addition to the Python language, you should look at the code module.

And code:

… provides facilities to implement read-eval-print loops in Python. Two classes and convenience functions are included which can be used to build applications which provide an interactive interpreter prompt.

The idea is that you let Python do all the hard stuff, up to whatever level you want to take over, and then you just write the part on top of that.

You may want to look at the source for IDLE, ipython, bpython, etc. for ideas.

Upvotes: 1

orip
orip

Reputation: 75537

Instead of using exec() to run the user input, try eval():

retval = eval(user_input)
sys.stdout.write(repr(retval) + "\n")

Upvotes: 0

Related Questions