Есть ли в Python функция "или равно", такая как || = в Ruby? - PullRequest
64 голосов
/ 14 октября 2010

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

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

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

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

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

, что намного лучше.

Ответы [ 5 ]

158 голосов
/ 14 ноября 2013

Принятый ответ хорош для диктовок, но заголовок ищет общий эквивалент оператора Ruby's || =.Обычный способ сделать что-то вроде || = в Python - это

x = x or new_value
14 голосов
/ 14 октября 2010

dict имеет setdefault().

Так что если request.session это dict:

request.session.setdefault('thing_for_purpose', 5)
9 голосов
/ 06 марта 2012

Установка значения по умолчанию имеет смысл, если вы делаете это в промежуточном программном обеспечении или чем-то еще, но если вам нужно значение по умолчанию в контексте одного запроса:

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 ...
5 голосов
/ 14 апреля 2017

Точный ответ: Нет. В 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).

0 голосов
/ 07 июля 2015

В общем, вы можете использовать dict[key] = dict.get(key, 0) + val.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...