Assigning a value to single underscore _ in Python/IPython interpreter

Question:

I created this function in Python 2.7 with ipython:

def _(v):
    return v

later if I call _(somevalue), I get _ = somevalue.

in[3]: _(3)
out[3]: 3
in[4]: print _
out[4]: 3

The function has disappeared! If I call _(4) I get:

TypeError: 'int' object is not callable

Why? What’s wrong with this function?

Asked By: eolandro

||

Answers:

_ is a special variable in interpreter, it is always assigned to the result of previous expression. So, you shoudn’t use it like that.

BTW the problem seems to be related to IPython shell, because your code works fine in normal python shell:

In normal python shell when you assign anything to the variable _ then it’ll remain assigned to that object only, and looses it special behaviour.


Python shell:

>>> 2*2
4
>>> _         #works as expected
4
>>> _ = 2     #after assignment, it's magic functionality is gone
>>> _*5       
10
>>> _
2

IPython shell:

In IPython _ behaves differently than python shell’s _; even if you assign it to some variable then also it is going to be updated as soon as you do some calculation.

In [1]: 2*2
Out[1]: 4

In [2]: _
Out[2]: 4

In [3]: _ = 10

In [4]: _*10
Out[4]: 100

In [5]: _
Out[5]: 100

From IPython’s docs:

The following GLOBAL variables always exist (so don’t overwrite
them!):

_ : (a single underscore) : stores previous output, like Python’s
default interpreter.
..

From python docs:

The special identifier _ is used in the interactive interpreter to
store the result of the last evaluation; it is stored in the
__builtin__ module. When not in interactive mode, _ has no special meaning and is not defined.

Note: The name _ is often used in conjunction with internationalization; refer to the documentation for the gettext
module for more information on this convention.

Answered By: Ashwini Chaudhary

The Python interpreter assigns the last expression value to _.

This behaviour is limited to the REPL interpreter only, and is intended to assist in interactive coding sessions:

>>> import math
>>> math.pow(3.0, 5)
243.0
>>> result = _
>>> result
243.0

The standard Python interpreter goes to some length to not trample on user-defined values though; if you yourself assign something else to _ then the interpreter will not overwrite that (technically speaking, the _ variable is a __builtin__ attribute, your own assignments are ‘regular’ globals). You are not using the standard Python interpreter though; you are using IPython, and that interpreter is not that careful.

IPython documents this behaviour explicitly:

The following GLOBAL variables always exist (so don’t overwrite them!):

  • [_] (a single underscore) : stores previous output, like Python’s default interpreter.

[…]

In the standard Python REPL environment, if you assigned something to _ you can still access the last expression result via __builtins__._ or by deleting the _ global that shadows it again (del _).

Outside of the Python interpreter, _ is by convention used as the name of the translatable text function (see the gettext module; external tools look for that function to extract translatable strings).

And, also by convention, using _ as an assignment target tells readers of your code that you are going to ignore that value; e.g. [random.random() for _ in range(5)] to generate a list of 5 random float values, or foo, bar, _ = three_values to signal a 3rd value from a tuple assignment will not be used. When _ is already used for a gettext function, __ can be used for the same purposes.

Answered By: Martijn Pieters

If you create a variable assigned to “_” it gets masked/masks the system variable _.

Answered By: Rentsy