要检查变量是否存在,如果退出,请使用原始值,否则请使用指定的新值。
在红宝石中,它是
var ||= var_new
如何在python中编写它?
PS:
我不知道name
的{{1}},我根本无法在Bing中搜索它。
答案 0 :(得分:23)
我认为那些不太确定条件赋值运算符(||=
)的作用的人会有一些混淆,还有一些关于如何在Ruby中生成变量的误解。
每个人都应该阅读this article这个主题。 TLDR引用:
一个常见的误解是|| = b等于a = a || b,但它的行为类似于|| a = b
在a = a ||中b,a在每次运行时由语句设置为某个值,而使用|| a = b,a仅在a逻辑上为假(即,如果它为零或假)时才设置,因为||是'短路'。也就是说,如果是||的左侧比较是正确的,没有必要检查右侧。
另一个非常重要的说明:
......变量赋值,即使没有运行,也会立即将该变量召唤成存在。
# Ruby
x = 10 if 2 == 5
puts x
即使第一行不会被运行,x也会存在于第二行,并且不会引发任何异常。
这意味着Ruby绝对确保在任何正确的条件发生之前,有一个值的变量容器。如果||=
未定义,则a
不会分配,如果a
是假的则会分配{再次,false
或nil
- nil
是Ruby中默认的 nothingness 值,同时保证a
定义。
好吧,如果定义了a
,则以下内容:
# Ruby
a ||= 10
实际上相当于:
# Python
if not a:
a = 10
而以下内容:
# Either language
a = a or 10
已关闭,但总是分配一个值,而前面的示例则没有。
如果未定义a
,则整个操作更接近:
# Python
a = None
if not a:
a = 10
因为a ||= 10
未定义a
时所做的事情的一个非常明确的例子是:
# Ruby
if not defined? a
a = nil
end
if not a
a = 10
end
在一天结束时,||=
运算符不能以任何“Pythonic”方式完全转换为Python,因为它依赖于生成的底层变量红宝石。
答案 1 :(得分:5)
在python中没有特别优雅的方式,因为让自己进入一个你不知道变量是否存在的情况并不是特别优雅。然而,这似乎最接近:
try:
var
except NameError:
var = var_new
我不熟悉ruby中的||=
运算符,但根据您所描述的,此块应具有正确的行为。也就是说,如果它是一个已经存在的变量,我们将var
保持原样,否则我们将其设置为var_new
。
答案 2 :(得分:4)
这大概就是你想要的东西:
var = var or var_new
Python对于不存在的变量的规则"非常严格;如果先前未分配var
,则会抛出异常。但是,如果var
评估为falsey ,则会收到var_new
的值。
我说这是"惯用你想要的"因为在Python中这种事物的惯用更大的结构是这样的:
var1 = None
var2 = None
var3 = None
# ... code here that may or may not set var1 through var3 ...
var1 = var1 or "default1"
var2 = var2 or "default2"
var3 = var3 or "default3"
另请注意,Python有一个相当广泛的概念" falsey"。此构造仅在var
不能被赋值为零,False或任何被认为是"为空的对象时才有效。 (例如""
,[]
,{}
...)。如果你真的希望它只在None上触发,你必须写更详细的
var = var if var is not None else var_new
并且,而不是这样做,我通常会寻找另一种方法来解决更大的问题。
最后,如果您可以构建您的代码,而不是......
var1 = "default1"
var2 = "default2"
var3 = "default3"
# ... code here that may or may not set var1 through var3 ...
...那么你应该,因为它更短,更简单,并且完全避免了无与错误的问题。
答案 3 :(得分:3)
不太安全,但另一种选择是:
var = locals().get('var', var_new)
答案 4 :(得分:1)
try: var
except NameError: var = var_new
或
var = locals().get('var', var_new)