Does a Python equivalent to the Ruby ||=
operator ("set the variable if the variable is not set") exist?
Example in Ruby :
variable_not_set ||= 'bla bla'
variable_not_set == 'bla bla'
variable_set = 'pi pi'
variable_set ||= 'bla bla'
variable_set == 'pi pi'
This question is related to
python
variables
conditional
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'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')
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.
No, there is no nonsense like that. Something we have not missed in Python for 20 years.
(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.
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/
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
>>>
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 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.
Source: Stackoverflow.com