我在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
为什么?这个函数有什么问题吗?
_
。>>> import math
>>> math.pow(3.0, 5)
243.0
>>> result = _
>>> result
243.0
标准的Python解释器会尽力避免覆盖用户定义的值,如果你自己将其他内容分配给_
,那么解释器不会覆盖它(严格来说,_
变量是一个__builtin__
属性,你自己的分配是“常规”的全局变量)。但你并没有使用标准的Python解释器;你正在使用IPython,而该解释器并不那么小心。
IPython 明确记录了这种行为:
在标准的Python REPL环境中,如果你把某些东西赋值给以下GLOBAL变量始终存在(因此不要覆盖它们!):
[_]
(一个下划线):存储以前的输出,就像Python的默认解释器一样。[...]
_
,你仍然可以通过__builtins__._
来访问最后一个表达式的结果,或者通过删除遮盖它的_
全局变量(del _
)来访问它。_
被用作可翻译文本函数的名称(请参见gettext
模块;外部工具会查找该函数以提取可翻译字符串)。_
用作赋值目标告诉代码读者您将忽略该值;例如,使用[random.random() for _ in range(5)]
生成一个包含5个随机浮点数值的列表,或者使用foo, bar, _ = three_values
表示元组赋值的第三个值将不会被使用。当_
已经用于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 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的文档:
以下GLOBAL变量始终存在(因此不要覆盖它们!):
_:(一个下划线):存储先前的输出,就像Python的默认解释器一样。 ..
来自Python的文档:
特殊标识符
_
用于交互式解释器中存储上次评估的结果; 存储在__builtin__
模块中。 在非交互模式下,_
没有特殊含义并且未定义。注意:名称
_
通常与国际化一起使用; 有关此约定的更多信息,请参阅gettext模块的文档。
如果你创建一个赋值给“_”的变量,它会掩盖系统变量“_”。
_
是什么? - Martijn Pieters