ChatGPT解决这个技术问题 Extra ChatGPT

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

这段代码中 for 后面的 _ 是什么意思?

if tbh.bag:
    n = 0
    for _ in tbh.bag.atom_set():
        n += 1
对于您的情况,使用 len(tbh.bag.atom_set())(如果返回值具有 __len__ 方法)或 sum(1 for _ in tbh.bag.atom_set()) 会更干净
pylint 中,虚拟变量名称的另一个选项是变量名称的前缀 dummy_。将此前缀与 pylint 一起使用,会使 pylint 不发出警告。您还可以为 pylint 配置虚拟变量模式以适应 __ 之类的内容。

n
ncoghlan

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

在交互式解释器会话中保存最后执行的表达式的结果(请参阅文档)。这个先例是由标准 CPython 解释器设置的,其他解释器也纷纷效仿 i18n 中的翻译查找(例如,参见 gettext 文档),如 raise forms.ValidationError(_("请输入正确的用户名")) 之类的代码作为一个通用的“一次性”变量名:表示函数结果的一部分被故意忽略(从概念上讲,它被丢弃了。),如代码中:label、has_label、_ = text.partition(':' ) 作为函数定义的一部分(使用 def 或 lambda),其中签名是固定的(例如,通过回调或父类 API),但这个特定的函数实现不需要所有参数,如代码所示: def callback(_): return True [很长一段时间这个答案没有列出这个用例,但它经常出现,正如这里所指出的,值得明确列出。]这个用例可能与翻译查找冲突用例,因此有必要避免使用 _ 作为一次性变量ny 代码块也将其用于 i18n 翻译(正是出于这个原因,许多人更喜欢双下划线 __ 作为他们的一次性变量)。 Linter 通常会识别此用例。例如 year, month, day = date() 如果后面的代码中没有使用 day,则会引发 lint 警告。如果确实不需要 day,则修复方法是编写年、月、_ = date()。与 lambda 函数相同,lambda arg: 1.0 创建一个需要一个参数但不使用它的函数,它将被 lint 捕获。解决方法是编写 lambda _: 1.0。未使用的变量通常隐藏错误/错字(例如,设置日期但在下一行使用 dya)。 Python 3.10 中添加的模式匹配功能将这种用法从“约定”提升到了与匹配语句相关的“语言语法”:在匹配情况下,_ 是通配符模式,运行时甚至不会将值绑定到那个案子。对于其他用例,请记住 _ 仍然是一个有效的变量名,因此仍将保持对象处于活动状态。在不希望这样做的情况下(例如释放内存或外部资源),显式的 del 名称调用将满足正在使用该名称的 linter,并立即清除对对象的引用。


您能否解释一下它在函数调用中的工作原理,例如:raise forms.ValidationError(_("请输入正确的用户名"))。我在 Django 代码中看到了这一点,目前还不清楚发生了什么。
这是用法 2 - 按照惯例,_ 是用于执行国际化和本地化字符串翻译查找的函数的名称。我很确定是 C gettext 库建立了该约定。
FWIW,我个人已经开始使用 __(双下划线)作为我的通用一次性变量,以避免与前两个用例中的任何一个发生冲突。
新兴的社区公约往往没有权威来源——只是对随着时间的推移出现的实践的观察。 FWIW,我是最近 PEP 8 更新的合著者之一,我的回答基于自 2002 年我开始专业使用 Python 以来,我看到 _ 用作变量名的 3 种不同方式。
该约定主要用于元组解包:a, __, c = iterable 立即告诉读者我们正在解包 3 元组,但仅使用第一个和最后一个值。如果我们改为编写 a, b, c = iterable,则阅读器(或自动代码检查器)可以合理地预期所有 abc 稍后会被使用(如果不是,它可能是某处出现错误的迹象)。
g
gsteff

它只是一个变量名,在 python 中习惯使用 _ 来表示一次性变量。它只是表示实际上并未使用循环变量。


你的意思是它不代表最后的返回值?
@steve 仅在 python shell 中
类似于 Prolog 中 _ 的使用
类似于 Matlab 中 ~ 的使用
请注意,在 cpython shell 中,如果您明确定义 _,它将永久停止保存前一个表达式的输出值。这似乎非常不一致,Python 语言标准需要解决这个问题。他们应该将 _ 定义为一次性名称,并阻止它被用作真正的标识符。
M
Marco Bonelli

下划线 _ 在 Python 中被视为“I don't Care”或“Throwaway”变量

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

下划线 _ 也用于忽略特定值。如果您不需要特定值或未使用这些值,只需将值分配给下划线即可。解包时忽略一个值 x, _, y = (1, 2, 3) >>> x 1 >>> y 3 忽略 range(10) 中 _ 的索引:do_something()


还有第三种用法,用于国际化函数 _("Hello world!")
在处理器级别,“for _ in range”和“for x in range”然后不使用 x 之间实际上有区别吗?还是只是为了人类可读性?
@iammax 使用 dis 模块我发现字节码没有区别。然而,人类可读性的好处是显而易见的。
w
wjandrea

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

用于在解释器中存储最后一个表达式的值。忽略特定值。 (所谓“我不在乎”) 给变量或函数的名称赋予特殊的含义和功能。用作“国际化 (i18n)”或“本地化 (l10n)”功能。分隔数字文字值的数字。

Here 是一篇不错的文章,其中包含 mingrammer 的示例。


事实上它是相当新的blog.pythonlibrary.org/2017/01/11/…
数字 3 和 5 并不真正适用于这个问题。 OP 询问单个下划线作为独立名称,但第 3 点谈到使用下划线作为更大名称的一部分,第 5 点谈到在文字中使用它,而不是名称。我只是提一下,以防任何新手感到困惑。 edit答案可能有助于澄清它。
M
MisterMiyagi

就 Python 语言而言,_ 一般没有特殊含义。它是一个有效的 identifier,就像 _foofoo__f_o_o_
唯一的例外是自 Python 3.10 以来的 match 语句:

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

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

不打算使用变量时的虚拟名称,但语法/语义需要名称。 # 迭代忽略内容 sum(1 for _ in some_iterable) # 解包忽略特定元素 head, *_ = values # 函数忽略其参数 def callback(_): return True

许多 REPL/shell 将最后一个顶级表达式的结果存储到 builtins._。交互式解释器中使用特殊标识符 _ 来存储上次评估的结果;它存储在内置模块中。不处于交互模式时,_ 没有特殊含义,也没有定义。 [来源] 由于查找名称的方式,除非被全局或本地 _ 定义遮蔽,否则裸露的 _ 指的是 builtins._ 。 >>> 42 42 >>> f'最后一个答案是 {_}' '最后一个答案是 42' >>> _ '最后一个答案是 42' >>> _ = 4 # shadow ``builtins._` ` with global ``_`` >>> 23 23 >>> _ 4 注意:一些 shell,如 ipython 不分配给 builtins._ 而是特殊情况 _。

在上下文国际化和本地化中,_ 用作主要翻译功能的别名。 gettext.gettext(message) 根据当前的全局域、语言和语言环境目录返回消息的本地化翻译。此函数通常在本地命名空间中别名为 _()(参见下面的示例)。