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

What is the purpose of the single underscore "_" variable in Python?

提问人:alwbtc 提问时间:5/5/2011 最后编辑:wjandreaalwbtc 更新时间:9/10/2023 访问量:422924

问:

此代码中 after 的含义是什么?_for

if tbh.bag:
    n = 0
    for _ in tbh.bag.atom_set():
        n += 1
python 变量 naming-conventions 元语法变量

评论


答:

254赞 gsteff 5/5/2011 #1

它只是一个变量名称,在 python 中通常用于一次性变量。它只是表示实际上没有使用循环变量。_

评论

7赞 alwbtc 5/5/2011
你的意思是它不代表最后一个返回值?
40赞 Gabi Purcaru 5/5/2011
仅在 Python shell 中@steve
4赞 Matthias 2/23/2016
类似于 Prolog 中 _ 的使用
5赞 PatriceG 4/25/2017
类似于 Matlab 中 ~ 的使用
2赞 theferrit32 4/2/2020
请注意,在 cpython shell 中,如果显式定义 ,它将永久停止保存上一个表达式的输出值。这似乎非常不一致,Python lang 标准需要解决这个问题。他们应该只定义为一个一次性名称,并阻止它被用作真正的标识符。__
1000赞 ncoghlan 5/5/2011 #2

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

  1. 在交互式中保存上次执行的表达式的结果 口译员会话(见文档)。这个先例是由标准CPython开创的 口译员和其他口译员也纷纷效仿

  2. 对于 i18n 中的翻译查找(例如,请参阅 gettext 文档),如在代码中

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

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

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

      def callback(_):
          return True
      

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

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

    Linters 经常识别此用例。例如,如果稍后未在代码中使用,将引发 lint 警告。如果确实不需要,解决方法是编写 .与 lambda 函数相同,创建一个需要一个参数但不使用它的函数,该函数将被 lint 捕获。解决方法是编写 .未使用的变量通常会隐藏错误/拼写错误(例如,set 但在下一行中使用)。year, month, day = date()daydayyear, month, _ = date()lambda arg: 1.0lambda _: 1.0daydya

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

    对于其他用例,请记住,这仍然是一个有效的变量名称,因此仍将保持对象处于活动状态。在不希望这样做的情况下(例如,释放内存或外部资源),显式调用既会让 linter 知道该名称正在被使用,会立即清除对对象的引用。_del name

评论

24赞 John C 5/19/2011
您能否解释一下它在函数调用中是如何工作的,例如:引发表单。ValidationError(_(“请输入正确的用户名”))。我在 Django 代码中看到了这一点,但不清楚发生了什么。
44赞 ncoghlan 5/20/2011
即用法 2 - 按照惯例,是用于执行国际化和本地化字符串翻译查找的函数的名称。我很确定是 C 库建立了这个约定。_gettext
50赞 ncoghlan 3/20/2012
FWIW,我个人已经开始使用(双下划线)作为我的通用一次性变量,以避免与前两个用例中的任何一个发生冲突。__
17赞 ncoghlan 6/28/2015
新兴的社区大会往往没有权威的来源,只是对随着时间的推移而出现的实践的观察。FWIW,我是最近 PEP 8 更新的合著者之一,我的答案是基于自 2002 年开始专业使用 Python 以来我看到的用作变量名称的 3 种不同方式。_
14赞 ncoghlan 2/29/2016
该约定主要用于元组解包:立即告诉读者我们正在解包一个 3 元组,但只使用第一个和最后一个值。如果我们改写 ,读者(或自动代码 linter)可以合理地期望所有 、 和稍后使用(如果不是,则可能是某处错误的迹象)。a, __, c = iterablea, b, c = iterableabc
133赞 Ashish25 12/2/2017 #3

在 Python 中,下划线被视为“我不在乎”或“扔掉”变量_

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

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

    解压缩时忽略值

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

    忽略索引

    for _ in range(10):     
        do_something()
    

评论

4赞 Jeff Younker 3/14/2018
还有第三种用法,即国际化功能。_("Hello world!")
11赞 iammax 7/12/2018
在处理器级别,“for _ in range”和“for x in range”与不使用 x 之间真的有区别吗?还是只是为了人类的可读性?
10赞 Alistair Carscadden 9/7/2018
@iammax 使用该模块,我发现字节码没有区别。然而,人类可读性的好处是显而易见的。dis
0赞 ado sar 1/22/2023
为什么如果我的东西没有显示这个值?print
1赞 wjandrea 6/28/2023
@ado 什么意思?你在打印什么,你期望看到什么?如果你这样做,那么 ,如果这就是你的意思,将打印 10。>>> 10>>> print(_)
33赞 Reck 3/13/2018 #4

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

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

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

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

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

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

这是一篇很好的文章,上面有 mingram 的示例。

评论

2赞 MichaelChirico 9/19/2018
事实上,这是很新的 blog.pythonlibrary.org/2017/01/11/......
3赞 wjandrea 11/27/2020
数字 3 和 5 并不真正适用于这个问题。OP 询问将单个下划线作为独立名称,但第 3 点讨论使用下划线作为更大名称的一部分,第 5 点讨论在文字而不是名称中使用它。我只是提到,以防任何新手感到困惑。编辑答案以澄清它可能会有所帮助。
13赞 MisterMiyagi 11/21/2019 #5

就Python语言而言,一般没有特殊的含义。它是一个有效的标识符,就像 或 一样。
唯一的例外是自 Python 3.10 以来的语句:
__foofoo__f_o_o_match

在语句中的模式中,是表示通配符的软关键字。casematch_

否则,任何特殊含义纯粹是约定俗成的。有几种情况很常见:_

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

    # 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_]

    由于名称的查找方式,除非被全局或局部定义所遮蔽,否则 bare 引用 .__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 不分配给 but special-case .ipythonbuiltins.__

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

    gettext.gettext(消息)

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