Python中单下划线“_”变量的目的是什么?

此代码中for之后的_是什么意思?

if tbh.bag:
n = 0
for _ in tbh.bag.atom_set():
n += 1
381271 次浏览

它只是一个变量名,在python中使用_作为一次性变量是常规的。它只是表明实际上没有使用循环变量。

_在Python中有3个主要的常规用途:

  1. 保存交互式中最后执行的表达式的结果 解释器会话(参见文档)。这个先例是由标准CPython设置的 译员和其他译员也纷纷效仿

  2. 对于国际化中的翻译查找(请参阅 gettext 例如留档),如代码

    raise forms.ValidationError(_("Please enter a correct username"))
    
  3. 作为通用的“一次性”变量名:

    1. 表示该部分 函数结果被故意忽略(从概念上讲,它被丢弃。),如代码中所示:

      label, has_label, _ = text.partition(':')
      
    2. 作为函数定义的一部分(使用deflambda),其中 签名是固定的(例如通过回调或父类API),但是 这个特定的函数实现不需要所有的 参数,如代码:

      def callback(_):
      return True
      

      [很长一段时间,这个答案没有列出这个用例,但它经常出现,正如这里所指出的,值得明确列出。

    此用例可能与翻译查找用例冲突,因此有必要避免在任何将其用于国际化翻译的代码块中使用_作为一次性变量(许多人更喜欢双下划线__作为他们的一次性变量正是出于这个原因)。

    Linter通常会识别这个用例。例如,如果代码后面没有使用dayyear, month, day = date()会引发lint警告。修复方法是,如果真的不需要day,则编写year, month, _ = date()。与lambda函数相同,lambda arg: 1.0创建了一个需要一个参数但不使用它的函数,这将被lint捕获。修复方法是编写lambda _: 1.0。未使用的变量通常隐藏bug /typo(例如设置day但在下一行使用dya)。

    Python 3.10中添加的模式匹配功能将这种用法从“约定”提升到“语言语法”,其中涉及match语句:在匹配情况下,_通配符模式,在这种情况下,运行时甚至没有将值绑定到符号。

    对于其他用例,请记住_仍然是一个有效的变量名,因此仍然会保持对象活着。在不希望这样做的情况下(例如释放内存或外部资源),显式的del name调用将既满足正在使用该名称的提示,立即清除对对象的引用。

下划线_在Python中被视为“我才不在乎”或“一次性”变量

  • python解释器将最后一个表达式值存储到名为_的特殊变量中。

    >>> 10
    10
    
    
    >>> _
    10
    
    
    >>> _ * 3
    30
    
  • The underscore _ is also used for ignoring the specific values. If you don’t need the specific values or the values are not used, just assign the values to underscore.

    Ignore a value when unpacking

    x, _, y = (1, 2, 3)
    
    
    >>> x
    1
    
    
    >>> y
    3
    

    忽略索引

    for _ in range(10):
    do_something()
    

在Python中使用下划线有5种情况。

  1. 用于在解释器中存储最后一个表达式的值。

  2. 用于忽略特定值。(所谓的“我不在乎”)

  3. 为变量或函数的名称赋予特殊含义和函数。

  4. 用作“国际化(国际化)”或“本地化(本地化)”函数。

  5. 分隔数字文字值的数字。

这里是一篇很好的文章,其中包含明格拉默的示例。

就Python语言而言,_通常没有特殊含义。它是一个有效的标识符,就像_foofoo__f_o_o_一样。
唯一的例外是Python 3.10之后的match语句:

match语句中的case模式中,_是表示通配符的软关键字。来源

否则,_的任何特殊含义纯粹是惯例。几种情况很常见:

  • 当变量不打算使用时,一个虚拟名称,但语法/语义学需要一个名称。

      # iteration disregarding content
    sum(1 for _ in some_iterable)
    # unpacking disregarding specific elements
    head, *_ = values
    # function disregarding its argument
    def callback(_): return True
    
  • 许多REPL/shell将最后一个顶级表达式的结果存储到builtins._

    特殊标识符_在交互式解释器中用于存储上次评估的结果;它存储在builtins模块中。当不在交互式模式下时,_没有特殊含义并且没有定义。[来源]

    由于名称的查找方式,除非被全局或本地_定义遮蔽,否则裸_指的是builtins._

      >>> 42
    42
    >>> f'the last answer is {_}'
    'the last answer is 42'
    >>> _
    'the last answer is 42'
    >>> _ = 4  # shadow ``builtins._`` with global ``_``
    >>> 23
    23
    >>> _
    4
    

    备注:一些shell(例如ipython)不分配给builtins._,而是分配给特殊情况_

  • 在上下文国际化和本地化中,_用作主翻译函数的别名。

    gettext.gettext(消息)

    根据当前全局域、语言和区域设置目录返回消息的本地化翻译。此函数通常在本地命名空间中别名为_()(请参阅下面的示例)。