68

我在 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

为什么?这个功能有什么问题?

4

3 回答 3

105

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功能时,__可以用于相同的目的。

于 2013-07-10T20:30:14.180 回答
31

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

顺便说一句,问题似乎与 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 模块的文档。

于 2013-07-10T20:30:06.367 回答
-1

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

于 2013-07-10T20:38:25.557 回答