Ответ 1
Принятый ответ хорош для dicts, но название требует общего эквивалента Ruby || = operator. Обычный способ сделать что-то вроде || = в Python
x = x or new_value
Если нет, то какой лучший способ сделать это?
Сейчас я делаю (для проекта django):
if not 'thing_for_purpose' in request.session:
request.session['thing_for_purpose'] = 5
но его довольно неудобно. В Ruby это будет:
request.session['thing_for_purpose'] ||= 5
что намного приятнее.
Принятый ответ хорош для dicts, но название требует общего эквивалента Ruby || = operator. Обычный способ сделать что-то вроде || = в Python
x = x or new_value
dict
имеет setdefault()
.
Итак, если request.session
является dict
:
request.session.setdefault('thing_for_purpose', 5)
Настройка значения по умолчанию имеет смысл, если вы делаете это в промежуточном программном обеспечении или что-то в этом роде, но если вам нужно значение по умолчанию в контексте одного запроса:
request.session.get('thing_for_purpose', 5) # gets a default
bonus: вот как сделать ||=
в Python.
def test_function(self, d=None):
'a simple test function'
d = d or {}
# ... do things with d and return ...
Точный ответ: Нет. Python не имеет одного встроенного оператора op
, который может перевести x = x or y
в x op y
.
Но это почти так. Оператор побитового или равного (|=
) будет функционировать, как описано выше, если оба операнда обрабатываются как булевы с оговоркой. (Какое предостережение? Ответ ниже, конечно.)
Во-первых, основная демонстрация функциональности:
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
Предостережение связано с тем, что python не является строго типизированным, и, таким образом, даже если значения обрабатываются как булевы в выражении, они не будут закорочены, если они переданы побитовому оператору. Например, предположим, что у нас есть логическая функция, которая очищает список и возвращает True
, если были удалены элементы:
def my_clear_list(lst):
if not lst:
return False
else:
del lst[:]
return True
Теперь мы можем увидеть короткозамкнутое поведение следующим образом:
x = True
lst = [1, 2, 3]
x = x or my_clear_list(lst)
print(x, lst)
Output: True [1, 2, 3]
Однако, переключение or
в поразрядное или (|
) устраняет короткое замыкание, поэтому выполняется функция my_clear_list
.
x = True
lst = [1, 2, 3]
x = x | my_clear_list(lst)
print(x, lst)
Output: True []
Выше, x = x | my_clear_list(lst)
эквивалентно x |= my_clear_list(lst)
.
В общем, вы можете использовать dict[key] = dict.get(key, 0) + val
.