我在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`
为什么?此功能有什么问题?
我在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`
为什么?此功能有什么问题?
_
。
Answers:
Python解释器将最后一个表达式值分配给_
。
此行为仅限于REPL解释器,并且旨在帮助进行交互式编码会话:
>>> import math
>>> math.pow(3.0, 5)
243.0
>>> result = _
>>> result
243.0
的标准Python解释去一些长度上虽然用户定义的值不踩; 如果您自己分配了其他内容,_
则解释器不会覆盖该内容(从技术上讲,该_
变量是一个__builtin__
属性,您自己的分配是“常规”全局变量)。但是,您没有使用标准的Python解释器。您正在使用IPython,并且该解释器不是那么小心。
IPython明确记录了此行为:
以下GLOBAL变量始终存在(因此请不要覆盖它们!):
[_]
(一个下划线):存储先前的输出,例如Python的默认解释器。[...]
在标准的Python REPL环境中,如果您分配了某些内容,_
您仍然可以通过__builtins__._
或删除_
再次遮蔽它的全局变量来访问最后一个表达式结果del _
。
_
按照惯例,在Python解释器之外,它被用作可翻译文本函数的名称(请参阅gettext
模块;外部工具会寻找该函数以提取可翻译字符串)。
而且,按照惯例,将其_
用作分配目标会告诉您的代码读者您将忽略该值;例如[random.random() for _ in range(5)]
,foo, bar, _ = three_values
将不使用生成5个随机浮点值的列表,或用信号表示元组分配的第三个值。当_
已经用于gettext
功能时,__
可以用于相同的目的。
_
是解释器中的特殊变量,它始终分配给先前表达式的结果。因此,您不应该那样使用它。
顺便说一句,问题似乎与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外壳:
在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的文档中:
以下GLOBAL变量始终存在(因此请不要覆盖它们!):
_ :(一个下划线):存储先前的输出,例如Python的默认解释器。..
从python docs:
特殊的标识符
_
在交互式解释器中用于存储上一次评估的结果。它存储在__builtin__
模块中。如果不在交互模式下,_
则没有特殊含义且未定义。注意:该名称
_
通常与国际化结合使用;有关此约定的更多信息,请参考gettext模块的文档。