我在 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
为什么?这个功能有什么问题?
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)]
,生成一个包含 5 个随机浮点值的列表,或者foo, bar, _ = three_values
从元组赋值中发出第三个值的信号将不会被使用。当_
已经用于某个gettext
功能时,__
可以用于相同的目的。
_
是解释器中的一个特殊变量,它总是分配给前一个表达式的结果。所以,你不应该那样使用它。
顺便说一句,问题似乎与 IPython 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文档:
交互式解释器中使用特殊标识符
_
来存储上次评估的结果;它存储在__builtin__
模块中。不处于交互模式时,_
没有特殊含义,也没有定义。注:该名称
_
常与国际化结合使用;有关此约定的更多信息,请参阅 gettext 模块的文档。
如果您创建分配给“_”的变量,它将被屏蔽/屏蔽系统变量_。