Python中单个下划线"_"变量的目的是什么?

alw*_*btc 570 python variables naming-conventions metasyntactic-variable

在这段代码中,_after 的含义是什么for

if tbh.bag:
   n = 0
   for _ in tbh.bag.atom_set():
      n += 1
Run Code Online (Sandbox Code Playgroud)

nco*_*lan 719

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

  1. 在交互式解释器会话中保存最后执行的表达式(/ statement)的结果.这个先例是由标准的CPython口译员设定的,其他口译员也纷纷效仿
  2. 对于i18n中的翻译查找( 例如,参见 gettext文档),如代码所示: raise forms.ValidationError(_("Please enter a correct username"))
  3. 作为通用的"一次性"变量名称,表示功能结果的一部分被故意忽略,如代码所示: label, has_label, _ = text.partition(':')

后两个目的可能会发生冲突,因此有必要避免def在任何代码块中使用它作为一次性变量,并将其用于i18n转换(许多人更喜欢双下划线lambda,因为它们是一次性变量,正是出于这个原因).

  • FWIW,我个人开始使用``__``(双下划线)作为我的通用一次性变量,以避免与前两个用例中的任何一个冲突. (41认同)
  • 这是用法2 - 按照惯例,`_`是用于执行国际化和本地化字符串转换查找的函数的名称.我很确定它是建立该约定的C`gettext`库. (40认同)
  • 你能解释它在函数调用中是如何工作的,例如:**raise forms.ValidationError(_("请输入正确的用户名"))**.我在Django代码中看到了这一点,目前还不清楚发生了什么. (18认同)
  • 紧急社区公约往往没有权威来源 - 只是观察随着时间推移出现的做法.FWIW,我是最近PEP 8更新的共同作者之一,我的答案是基于我在2002年开始专业使用Python时用作变量名称的3种不同方式. (14认同)
  • 该约定主要用于元组解包:`a,__,c = iterable`立即告诉读者我们正在解包3元组,但仅使用第一个和最后一个值.如果我们改为写'a,b,c = iterable',那么读者(或自动代码linter)可以合理地期望以后使用所有的`a`,`b`和`c`(如果它们是不,它可能是某处某个bug的标志). (10认同)
  • @jpmc26:我添加了一个指向stdlib gettext文档中最直接相关部分的链接:https://docs.python.org/3/library/gettext.html#localizing-your-module(有更高级别的il8n模块输出那里,但这个特殊的约定来自C`gettext` API,Python从那里采用它 (2认同)
  • 它似乎也用于分隔数字的数字?`>>> 1_000_123`导致`1000123` (2认同)
  • @MiserableVariable这是3.6中用于编写数字文字的新功能,它不涉及将`_`用作*变量*.它更接近于使用它作为更大的标识符的一部分,如`functools.total_ordering`或`contextlib.redirect_stdout`. (2认同)
  • 考虑扩展一下你对函数参数的答案,这样我们就可以从这样的问题重定向到这里:[Python's lambda with no Variables?](/sf/ask/2083711731/ )、[Python 下划线作为函数参数](/sf/ask/405109421/) 或更新的[“_”在 lambda 函数中意味着什么?] (/sf/ask/4003792271/) (2认同)

gst*_*eff 191

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

  • @steve只在python中_shell_ (31认同)
  • 你的意思是它不代表最后返回的值? (5认同)
  • 类似于在Prolog中使用_ (3认同)
  • 类似于在Matlab中使用〜 (2认同)
  • 请注意,在 cpython shell 中,如果显式定义“_”,它将永久停止保存前一个表达式的输出值。这看起来非常不一致,Python 语言标准需要解决这个问题。他们应该将“_”定义为一次性名称并阻止其被用作真正的标识符。 (2认同)

Ash*_*ahu 66

在Python中,下划线_被视为" 我不关心 "或" 丢失 "变量

  • @iammax 使用`dis` 模块我发现字节码没有区别。然而,人类可读性的好处是显而易见的。 (6认同)
  • 在处理器级别,"for _ in range"和"for x in range"之间是否存在实际差异,然后不使用x?还是只是为了人类的可读性? (3认同)
  • 还有第三种用法,即国际化函数`_("Hello world!")`. (2认同)

Rec*_*eck 18

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

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

  2. 忽略具体值.(所谓的"我不在乎")

  3. 赋予vartiables或函数名称特殊的含义和功能.

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

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

是一篇很好的文章,有mingrammer的例子.

  • 数字 3 和 5 并不真正适用于这个问题。OP 询问单个下划线作为独立名称,但第 3 点讨论使用下划线作为更大名称的一部分,第 5 点讨论在文字中使用它,而不是名称。我只是提一下以防新手感到困惑。[编辑]答案以澄清它可能会有所帮助。 (3认同)
  • 事实上它是相当新的https://www.blog.pythonlibrary.org/2017/01/11/new-in-python-underscores-in-numeric-literals/ (2认同)

Mis*_*agi 7

就 Python 语言而言,_没有特殊意义。它是一个有效的标识符,就像_foo,foo_或 一样_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
    
    Run Code Online (Sandbox Code Playgroud)
  • 许多 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
    
    Run Code Online (Sandbox Code Playgroud)

    注意:一些外壳,例如ipython不分配给builtins._但特殊情况_

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

    gettext.gettext(消息)

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