在Python / IPython解释器中为单个下划线_赋值

时间:2013-07-10 20:28:54

标签: python function ipython interpreter read-eval-print-loop

我在Python 2.7中用ipython

创建了这个函数
def _(v):
    return v

稍后,如果我致电_(somevalue),我会收到_ = somevalue

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

功能消失了!如果我致电_(4),我会:

TypeError: 'int' object is not callable`

为什么呢?这个功能出了什么问题?

3 个答案:

答案 0 :(得分:105)

Python解释器将最后一个表达式值赋给_

此行为仅限于REPL interpreter,旨在协助交互式编码会话:

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

标准 Python解释器虽然在某种程度上不会践踏用户定义的值;如果您自己将 else 分配给_,那么解释器就不会覆盖它(从技术上讲,_ variable is a __builtin__ attribute,您自己的作业是常规'全局)。你没有使用标准的Python解释器;你正在使用IPython,那个解释器并不那么谨慎。

IPython documents this behaviour explicitly

  

以下GLOBAL变量始终存在(所以不要覆盖它们!):

     
      
  • [_](单个下划线):存储以前的输出,如Python的默认解释器。
  •   
     

[...]

在标准的Python REPL环境中,如果您为_分配了一些内容,您仍然可以通过__builtins__._或通过删除再次隐藏它的_全局来访问最后一个表达式结果({ {1}})。

在Python解释器之外,del _按惯例用作可翻译文本函数的名称(请参阅gettext module;外部工具查找该函数以提取可翻译字符串)。

而且,按照惯例,使用_作为赋值目标会告诉读者您的代码将忽略该值;例如_生成一个包含5个随机浮点值的列表,或者[random.random() for _ in range(5)]来表示来自元组赋值的第3个值将不会被使用。当foo, bar, _ = three_values已用于_功能时,gettext可用于相同目的。

答案 1 :(得分:30)

_是解释器中的特殊变量,它始终分配给前一个表达式的结果。所以,你不应该那样使用它。

这个问题似乎与IPython shell有关,因为你的代码在普通的python shell中工作正常:

在普通的python shell中,当您为变量_分配任何内容时,它仍将仅分配给该对象,并使其失去特殊行为。


Python shell:

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

IPython shell

在IPython中_的行为与python shell的_不同;即使你将它分配给某个变量,它也会在你做一些计算后立即更新。

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

来自IPython的docs

  

以下GLOBAL变量始终存在(因此请勿覆盖   它们):

     

_ :(单个下划线):存储以前的输出,就像Python一样   默认解释器。   ..

来自python docs

  

特殊标识符_用于交互式解释器   存储上次评估的结果;它存储在   __builtin__模块。当不处于交互模式时,_没有特殊含义,也没有定义。

     

注意:名称_通常与国际化一起使用;请参阅gettext的文档   模块以获取有关此约定的更多信息。

答案 2 :(得分:-2)

如果创建一个分配给“_”的变量,它将被屏蔽/屏蔽系统变量_。