2

I was reading through this question and began to wonder why the _ character only represents the result of the last executed statement in interactive modes, and not through actual script execution.

Script execution mode:

$ python3 -c '1;print(_)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name '_' is not defined

Interactive mode:

Tue Dec 18 09:41:20 CST 2018 | /Users/user
$ python3
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 03:03:55) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1
1
>>> print(_)
1

What is the reasoning for this "feature" only being available in interpretive modes?

blacksite
  • 12,086
  • 10
  • 64
  • 109
  • 5
    not saying that this is the reason, but I doubt anyone would want to see this in production code. – Ma0 Dec 18 '18 at 15:46
  • 1
    @Ev.Kounis, no doubt -- this is more of just a "curious question" than "I want to use this feature that really only obfuscates" – blacksite Dec 18 '18 at 15:52
  • I do not have a reference but I would say that as far as the interactive shell goes, it is for ease of use (typing `_` instead of a long variable name can save you a second or two). Now as far as scripts go, having it in there would be a nightmare. – Ma0 Dec 18 '18 at 15:56
  • 2
    You asked for the reasoning, but the mechanism is https://docs.python.org/3/library/sys.html#sys.displayhook – user2357112 Dec 18 '18 at 16:05

1 Answers1

1

The major use case for the sys.displayhook() is to provide the feature in interactive mode where a non-None expression result will print magically for you, so you don't have to explicitly print() it. It's primarily used for just kicking up the interpreter to experiment with things:

>>> None
>>> 1 + 7
8

It's only a short step from this auto-printing to realise that you may want to keep doing stuff with the result in interactive mode. Hence the value is also stored in builtins._ so that you can re-use it:

>>> 1 + 7
8
>>> _ * 3 -.5
23.5
>>> _ * _
552.25
>>> import math
>>> math.sqrt(_ + 7)
23.648467180770936

>>> f"I am {5 * 11} years old."
'I am 55 years old.'
>>> _[:-1] + ", and I sometimes feel it!"
'I am 55 years old, and I sometimes feel it!'

That basically makes interactive mode a handy desktop interpreter, something you can easily experiment with, rather than having to explicitly assign everything to variables so you can re-use it or, even worse, writing monstrosities like:

>>> 1 + 7
8
>>> (1 + 7) * 3 -.5
23.5
>>> ((1 + 7) * 3 -.5) * ((1 + 7) * 3 -.5)
552.25
>>> import math
>>> math.sqrt(((1 + 7) * 3 -.5) * ((1 + 7) * 3 -.5) + 7)
23.648467180770936

And the reason why it's not so useful in a program is because a program won't generally be used for experimentation in the same way as interactive mode.

I would hope that, by the time you get around to writing a program, you really shouldn't have to be experimenting :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953