Does Python have an "or equals" function like ||= in Ruby?
If not, what is the best way to do this?
Right now I'm doing (f开发者_StackOverflowor a django project):
if not 'thing_for_purpose' in request.session:
request.session['thing_for_purpose'] = 5
but its pretty awkward. In Ruby it would be:
request.session['thing_for_purpose'] ||= 5
which is much nicer.
Jon-Eric's answer's is good for dicts, but the title seeks a general equivalent to ruby's ||=
operator.
A common way to do something like ||=
in Python is
x = x or new_value
Precise answer: No. Python does not have a single built-in operator op
that can translate x = x or y
into x op y
.
But, it almost does. The bitwise or-equals operator (|=
) will function as described above if both operands are being treated as booleans, with a caveat. (What's the caveat? Answer is below of course.)
First, the basic demonstration of functionality:
x = True
x
Out[141]: True
x |= True
x
Out[142]: True
x |= False
x
Out[143]: True
x &= False
x
Out[144]: False
x &= True
x
Out[145]: False
x |= False
x
Out[146]: False
x |= True
x
Out[147]: True
The caveat is due python not being strictly-typed, and thus even if the values are being treated as booleans in an expression they will not be short-circuited if given to a bitwise operator. For example, suppose we had a boolean function which clears a list and returns True
iff there were elements deleted:
def my_clear_list(lst):
if not lst:
return False
else:
del lst[:]
return True
Now we can see the short-circuited behavior as so:
x = True
lst = [1, 2, 3]
x = x or my_clear_list(lst)
print(x, lst)
Output: True [1, 2, 3]
However, switching the or
to a bitwise or (|
) removes the short-circuit, so the function my_clear_list
executes.
x = True
lst = [1, 2, 3]
x = x | my_clear_list(lst)
print(x, lst)
Output: True []
Above, x = x | my_clear_list(lst)
is equivalent to x |= my_clear_list(lst)
.
dict
has setdefault()
.
So if request.session
is a dict
:
request.session.setdefault('thing_for_purpose', 5)
Setting a default makes sense if you're doing it in a middleware or something, but if you need a default value in the context of one request:
request.session.get('thing_for_purpose', 5) # gets a default
bonus: here's how to really do an ||=
in Python.
def test_function(self, d=None):
'a simple test function'
d = d or {}
# ... do things with d and return ...
In general, you can use dict[key] = dict.get(key, 0) + val
.
精彩评论