Python 条件赋值运算符

是否存在与 Ruby||=操作符(“如果变量未设置,则设置变量”)等价的 Python?

Ruby 中的例子:

 variable_not_set ||= 'bla bla'
variable_not_set == 'bla bla'


variable_set = 'pi pi'
variable_set ||= 'bla bla'
variable_set == 'pi pi'
151691 次浏览

不,替代品是:

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

然而,想要使用这个结构是代码流过于复杂的一个迹象:

try:
v = complicated()
except ComplicatedError: # complicated failed
v = 'fallback value'

永远不要不确定 v是否设置。如果它是许多可以设置或不可以设置的选项之一,请使用 dictionary 及其允许默认值的 get方法。

不,不知道定义了哪些变量是一个 bug,而不是 Python 中的一个特性。

使用措辞代替:

d = {}
d.setdefault('key', 1)
d['key'] == 1


d['key'] = 2
d.setdefault('key', 1)
d['key'] == 2

我不确定我是否正确理解了这里的问题... 试图“读取”一个“未定义”的变量名的值将触发 NameError。(见 在这里,巨蟒有“名字”,不是变量...)。

= = EDIT = =

正如 delnan 在注释中指出的那样,下面的代码并不健壮,在许多情况下都会中断..。

尽管如此,如果你的变量“存在”,但是有某种虚拟值,比如 None,那么下面的方法可以起作用:

>>> my_possibly_None_value = None
>>> myval = my_possibly_None_value or 5
>>> myval
5
>>> my_possibly_None_value = 12
>>> myval = my_possibly_None_value or 5
>>> myval
12
>>>

(见 关于真理价值的这一段)

我通常是这样做的:

def set_if_not_exists(obj,attr,value):
if not hasattr(obj,attr): setattr(obj,attr,value)

我很惊讶没有人给出这个答案。它不像 Ruby 的 ||=那样“内置”,但它基本上是等价的,仍然是一行程序:

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

当然,locals()只是一本字典,所以你可以这样做:

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

我会用

x = 'default' if not x else x

比你在这里提出的所有建议都要短得多,而且直奔主题。阅读,“如果 x 没有设置,那么将 x 设置为‘ default’,否则将其保持为 x。”然而,如果你需要 None0False""作为有效值,那么你需要改变这种行为,例如:

valid_vals = ("", 0, False) # We want None to be the only un-set value


x = 'default' if not x and x not in valid_vals else x

这种东西也只是乞求被转换成一个可以在任何地方轻松使用的函数:

setval_if = lambda val: 'default' if not val and val not in valid_vals else val

在这一点上,您可以使用它作为:

>>> x = None # To set it to something not valid
>>> x = setval_if(x) # Using our special function is short and sweet now!
>>> print x # Let's check to make sure our None valued variable actually got set
'default'

最后,如果您真的丢失了 Ruby 中缀符号,您可以按照这个家伙的黑客技巧来重载 ||=|(或类似的东西) : http://code.activestate.com/recipes/384122-infix-operators/

在 Python 2.5和更高版本中有条件赋值——语法不是很明显,因此很容易被忽略。你要这么做:

x = true_value if condition else false_value

如需进一步参考,请参阅 Python 2.5文档

(无可奉告,否则我就这么做了)我认为上面关于检查当地人的建议是不太正确的。它应该是:

foo = foo if 'foo' in locals() or 'foo' in globals() else 'default'

在任何情况下都是正确的。

然而,尽管它得到了好评,我不认为这是一个很好的 Ruby 操作符的类比。因为 Ruby 操作符不仅仅允许左边的简单名称:

foo[12] ||= something
foo.bar ||= something

异常方法可能是最接近的模拟方法。

我认为,如果你在字典中查找什么,你要找的是 setdefault方法:

(Pdb) we=dict()
(Pdb) we.setdefault('e',14)
14
(Pdb) we['e']
14
(Pdb) we['r']="p"
(Pdb) we.setdefault('r','jeff')
'p'
(Pdb) we['r']
'p'
(Pdb) we[e]
*** NameError: name 'e' is not defined
(Pdb) we['e']
14
(Pdb) we['q2']

* * * 键错误: ‘ q2’ (pdf)

在我的示例中需要注意的重要事项是,当且仅当 setdefault方法引用的键不存在时,setdefault方法才更改字典。

我这样做... 只是为了分享,以防对观察所或其他人有用..。

def iff(value, default):
return default if not value else value

用法:

z = iff(x,y) # z = x if and only if x is not null otherwise y