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


618

此代码中的_after 是什么意思for

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


5
对于您的情况,最好是len(tbh.bag.atom_set())(如果返回的值具有__len__方法)或sum(1 for _ in tbh.bag.atom_set())
Nick T16年

pylint另一种选择哑变量名的前缀dummy_变量名。将此前缀与一起使用pylintpylint不会发出警告。您也可以配置虚拟变量模式pylint以适应__
Trevor Boyd Smith,

Answers:


780

_ 在Python中有4种主要的常规用法:

  1. 在交互式解释器会话中保存上次执行的表达式的结果。此先例是由标准CPython解释器设置的,其他解释器也纷纷效仿
  2. 有关在i18n中进行翻译查找的信息,请参见 gettext 例如,文档),如代码所示: raise forms.ValidationError(_("Please enter a correct username"))
  3. 作为通用“一次性”的变量名指示函数结果的一部分被故意忽略(在概念上,它被丢弃。),如类似的代码: label, has_label, _ = text.partition(':')
  4. 作为函数定义的一部分(使用deflambda),其中的签名是固定的(例如,通过回调或父类API),但是此特定函数实现不需要所有参数,如代码所示:callback = lambda _: True

(很长一段时间以来,这个答案只列出了前三个用例,但是第四个用例经常出现,如前所述 这里,将值得明确列出)

后者的“抛弃型变量或参数名称”用例可能与翻译查找用例冲突,因此有必要避免_在也将其用于i18n转换的任何代码块中将其用作抛弃型变量(许多人更喜欢双下划线,__正是由于这个原因而将其作为一次性变量)。


19
您能否解释一下它在函数调用中的工作方式,例如:raise Forms.ValidationError(_(“请输入正确的用户名”))。我已经在Django代码中看到了这一点,目前尚不清楚发生了什么。
约翰·C

41
用法2-按照惯例,_是用于进行国际化和本地化字符串转换查找的函数的名称。我很确定这是gettext约定的C 库。
ncoghlan

43
FWIW,我个人开始使用__(双下划线)作为通用的一次性变量,以避免与前两个用例之一冲突。
ncoghlan 2012年

14
新兴的社区惯例往往没有权威来源-只是对随着时间推移出现的做法的观察。FWIW,我是PEP 8最新更新的合著者之一,我的答案基于_自2002
。– ncoghlan

12
该约定主要用于元组拆包:a, __, c = iterable立即告诉读者我们正在拆解3元组,但仅使用第一个和最后一个值。如果我们不是写a, b, c = iterable,读者(或自动代码棉短绒)可以合理预期的是abc稍后使用(如果他们不是,它可能是一个错误的地方的标志)。
ncoghlan '16

207

它只是一个变量名,在python中通常_用于丢弃变量。它仅表示循环变量未实际使用。


5
您的意思是它不代表最后返回的值?
alwbtc 2011年

31
@steve仅在python shell中
Gabi Purcaru 2011年

4
类似于在序言中使用_
Matthias

3
类似于在Matlab中使用
〜– PatriceG

请注意,在cpython shell中,如果您明确定义_,它将永久停止保存前一个表达式的输出值。这似乎非常不一致,Python lang标准需要解决这个问题。它们应该只定义_为一个一次性的名称,并阻止其用作真实标识符。
theferrit32

78

下划线在Python中_被视为“ 我不在乎 ”或“ 抛出 ”变量

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

    >>> 10 
    10
    
    >>> _ 
    10
    
    >>> _ * 3 
    30
  • 下划线_也用于忽略特定值。如果不需要特定值或不使用这些值,只需将这些值分配给下划线即可。

    开箱时忽略值

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

    忽略索引

    for _ in range(10):     
        do_something()

2
还有第三种用法,用于国际化功能_("Hello world!")
杰夫·尤尼克

3
在处理器级别,“ for _ in range”和“ for x in range”之间实际有区别,然后不使用x吗?还是仅出于人类可读性?
iammax

1
@iammax使用该dis模块,我发现字节码没有区别。但是,人类可读性的好处是显而易见的。
Alistair Carscadden

21

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

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

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

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

  4. 用作“国际化(i18n)”或“本地化(l10n)”功能。

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

是一篇不错的文章,上面有mingrammer的示例。


2
实际上,这是一个非常新的 blog.pythonlibrary.org/2017/01/11/…–
MichaelChirico

3

就Python语言而言,_没有特殊含义。与或一样,它是有效的标识符_foofoo__f_o_o_

的任何特殊含义_纯属约定。常见几种情况:

  • 如果不打算使用变量,但是语法/语义需要一个虚拟名称。

    # 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

    注意:某些外壳程序(例如)ipython不分配给builtins._而是特例_

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

    gettext.gettext(消息)

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.