Python conditional assignment operator
Does a Python equivalent to the Ruby ||=
operator ("set the variable if the variable is not set") exist?
Example in Ruby :
variable_n开发者_StackOverflowot_set ||= 'bla bla'
variable_not_set == 'bla bla'
variable_set = 'pi pi'
variable_set ||= 'bla bla'
variable_set == 'pi pi'
I'm surprised no one offered this answer. It's not as "built-in" as Ruby's ||=
but it's basically equivalent and still a one-liner:
foo = foo if 'foo' in locals() else 'default'
Of course, locals()
is just a dictionary, so you can do:
foo = locals().get('foo', 'default')
I would use
x = 'default' if not x else x
Much shorter than all of your alternatives suggested here, and straight to the point. Read, "set x to 'default' if x is not set otherwise keep it as x." If you need None
, 0
, False
, or ""
to be valid values however, you will need to change this behavior, for instance:
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
This sort of thing is also just begging to be turned into a function you can use everywhere easily:
setval_if = lambda val: 'default' if not val and val not in valid_vals else val
at which point, you can use it as:
>>> 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'
Finally, if you are really missing your Ruby infix notation, you could overload ||=|
(or something similar) by following this guy's hack: http://code.activestate.com/recipes/384122-infix-operators/
No, the replacement is:
try:
v
except NameError:
v = 'bla bla'
However, wanting to use this construct is a sign of overly complicated code flow. Usually, you'd do the following:
try:
v = complicated()
except ComplicatedError: # complicated failed
v = 'fallback value'
and never be unsure whether v
is set or not. If it's one of many options that can either be set or not, use a dictionary and its get
method which allows a default value.
There is conditional assignment in Python 2.5 and later - the syntax is not very obvious hence it's easy to miss. Here's how you do it:
x = true_value if condition else false_value
For further reference, check out the Python 2.5 docs.
(can't comment or I would just do that) I believe the suggestion to check locals above is not quite right. It should be:
foo = foo if 'foo' in locals() or 'foo' in globals() else 'default'
to be correct in all contexts.
However, despite its upvotes, I don't think even that is a good analog to the Ruby operator. Since the Ruby operator allows more than just a simple name on the left:
foo[12] ||= something
foo.bar ||= something
The exception method is probably closest analog.
No, not knowing which variables are defined is a bug, not a feature in Python.
Use dicts instead:
d = {}
d.setdefault('key', 1)
d['key'] == 1
d['key'] = 2
d.setdefault('key', 1)
d['key'] == 2
I usually do this the following way:
def set_if_not_exists(obj,attr,value):
if not hasattr(obj,attr): setattr(obj,attr,value)
I do this... just sharing in case it's useful for the OP or anyone else...
def iff(value, default):
return default if not value else value
Usage:
z = iff(x,y) # z = x if and only if x is not null otherwise y
I think what you are looking for, if you are looking for something in a dictionary, is the setdefault
method:
(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']
*** KeyError: 'q2' (Pdb)
The important thing to note in my example is that the setdefault
method changes the dictionary if and only if the key that the setdefault
method refers to is not present.
I am not sure I understand the question properly here ... Trying to "read" the value of an "undefined" variable name will trigger a NameError
. (see here, that Python has "names", not variables...).
== EDIT ==
As pointed out in the comments by delnan, the code below is not robust and will break in numerous situations ...
Nevertheless, if your variable "exists", but has some sort of dummy value, like None
, the following would work :
>>> 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
>>>
(see this paragraph about Truth Values)
精彩评论