Есть ли у Python функция" или равно", например | / = в Ruby?


Если нет, то каков наилучший способ сделать это?

прямо сейчас я делаю (для проекта django):

if not 'thing_for_purpose' in request.session:
    request.session['thing_for_purpose'] = 5

но это довольно неудобно. В Ruby это будет:

request.session['thing_for_purpose'] ||= 5

что гораздо приятнее.

5 54

5 ответов:

принятый ответ хорош для диктов, но название ищет общий эквивалент оператора Ruby's||=. Обычный способ сделать что-то вроде ||= в 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

бонус: вот как на самом деле сделать ||= в 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.

но, это почти делает. побитовый оператор or-equals (|=)будет функция, как описано выше, если оба операнда рассматриваются как булевы, с оговоркой. (В чем тут оговорка? Ответ, конечно, ниже.)

во-первых, основная демонстрация функциональность:

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.