【问题标题】:Python equivalent of Perl/Ruby ||= [duplicate]Python 等价于 Perl/Ruby ||= [重复]
【发布时间】:2012-02-21 23:58:19
【问题描述】:

可能重复:
Python conditional assignment operator

抱歉这么简单的问题,但谷歌搜索 ||= 不是很有帮助;)

Python 中是否存在与 Ruby 和 Perl 中的 ||= 语句等效的语句?

例如:

foo = "hey"
foo ||= "what"    # assign foo if it's undefined
# foo is still "hey"

bar ||= "yeah"
# bar is "yeah"

还有什么是这样的通用术语?条件赋值是我的第一个猜测,但 Wikipedia page 并不是我想的那样。

【问题讨论】:

  • 是的,它似乎是重复的。谢谢亚当!
  • $foo ||= "what" 将重新分配 $foo 如果它已经是 false。当然undef 是假的,但零和空字符串也是如此。要仅重新分配未定义的值,请改用斜杠,例如 $foo //= "what"
  • 请注意,//(及其扩展名,//=)是在 perl 5.10 中添加的。如果您仍然卡在 5.8.x 上,您将无法使用 //=(如果可能,您应该认真考虑升级)。

标签: python ruby perl


【解决方案1】:

有点冗长,但最简单的是

foo = "hey"
foo = foo or "what"
#foo is still "hey"

bar = None
bar = bar or "yeah"
#bar is "yeah"

你也可以使用三元运算符

bar = None
bar = bar if bar else "yeah"

但是,如果我理解你的意思,||= 分配了以前未定义的变量,没有抱怨?我不知道。

要在本地范围内做到这一点,这只丑小鸭可以工作

bar = locals()['bar'] if 'bar' in locals() else 'yeah'

编辑:

刚看到副本,它也有很多解决方案 :) 对于那些懒得看的人,他们还包括我最后一个更好的变体

foo = foo if 'foo' in locals() else 'hey'

但这不适用于未定义的变量,只会替换虚假值,并且未定义会引发NameError。 OTOH,下一个将仅适用于未定义并始终保持相同的预先存在的虚假值,正如@Borodin 所说,就像 Perl 中的 //=

foo = locals().get('foo','hey')

当然,有人使用了例外:(

try:
   v
except NameError:
   v = 'bla bla'

【讨论】:

  • 不,||= 将重新分配一个变量,如果它是 false。请参阅我对这个问题的评论。为什么会收到投诉?
  • 感谢您的回复,起初我没有注意到细微差别。 bar = None 是它工作所必需的,否则它会抛出 NameError。对于相同的行为,您需要您的locals()['bar'] sn-p。再次感谢:)
  • @borodin 我不是 Rubyist,我只将它用于像 Chef 这样的愚蠢的东西。我只是说我不知道​​ Ruby 中的 undef 是错误的,因为 Python 中并非如此(未定义的引用引发异常)。无论如何,感谢您的 cmets,我学到了一些东西:)
【解决方案2】:

在 Python 中你几乎不会有未定义的变量,当你这样做时通常意味着你犯了一个错误。然而,方便的是,大多数常用作为默认值的值(空容器、零长度字符串、零和None)在 Python 中是“假的”,所以你有时会看到这样的东西利用布尔运算符如何在 Python 中工作:

name = name or "Guido"   # if name is empty, set it to "Guido"
numb = numb or 42        # if numb is zero, set it to 42

这样做的原因是如果第一个参数是“真实的”,Python 会停止评估 or,这称为短路,并且在任何一种情况下都会返回实际参数,而不仅仅是 TrueFalse ,作为其结果。因此,如果 name 是“Jim”,那么 "Jim" or "Guido" 的计算结果为 "Jim",因为 "Jim" 是一个非零长度字符串,因此是“真实的”。

当然,当您不知道您正在处理的值的类型和/或“虚假”值是有效值时,这不会很好地工作。但是,它与配置文件和raw_input() 之类的东西配合得很好,其中缺少的值将返回一个空字符串:

name = raw_input("What is your name? ") or "Guido"

在处理字典中的项目时使用另一个常见的习惯用法。字典类的get() 方法允许您指定一个默认值,以在该变量不在字典中时使用。

name = values.get("name", "Guido")

当您的函数已使用**kwargs 约定传递关键字参数时,可以使用此选项。您也可以将它与变量一起使用,因为 globals()locals() 函数分别将当前范围内的所有全局或局部变量作为字典返回:

name = locals().get("name", "Guido")

但是,正如我所说,您在 Python 中很少有实际未定义的变量。例如,在 Web 框架之类的情况下,您将作为字典传递查询字符串参数,并且可以在其上使用字典的 .get() 方法。

在名称实际上不存在的极少数情况下(例如,您的配置文件采用 Python 语法,并且您将其作为 Python 模块导入而不是解析它,并且您希望用户能够省略一些值...或同样古怪的东西)然后您可以使用getattr(),它(如字典的.get())接受默认值:

import config
name = getattr(config, "name", "Guido")    # rather than just name.config

或者让它抛出 NameError 并抓住它。

【讨论】:

    【解决方案3】:

    不确定名称。我能想到的最好的方法是:

    >>> a = 'foo'
    >>> a = 'a' in locals() and a or 'what'
    >>> a
    'foo'
    >>> b = 'b' in locals() and b or 'yeah'
    >>> b
    'yeah'
    

    【讨论】:

      猜你喜欢
      • 2011-03-18
      • 2019-08-15
      • 2012-11-26
      • 1970-01-01
      • 2010-10-22
      • 2011-08-18
      • 2019-03-14
      • 1970-01-01
      • 2010-09-23
      相关资源
      最近更新 更多