web-dev-qa-db-fra.com

Est-ce que Python a une fonction "ou égale" comme || = en Ruby?

Si non, quel est le meilleur moyen de le faire?

En ce moment je fais (pour un projet Django):

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

mais c'est assez maladroit. En Ruby ce serait:

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

ce qui est beaucoup mieux.

59
Sean W.

La réponse acceptée est bonne pour les dict, mais le titre cherche un équivalent général à l'opérateur || = de Ruby. Une façon courante de faire quelque chose comme || = en Python est

x = x or new_value
150
Joseph Sheedy

dict a setdefault() .

Donc, si request.session est une dict:

request.session.setdefault('thing_for_purpose', 5)
14
Jon-Eric

Définir une valeur par défaut est logique si vous le faites dans un middleware ou quelque chose du genre, mais si vous avez besoin d'une valeur par défaut dans le contexte d'une requête:

request.session.get('thing_for_purpose', 5) # gets a default

bonus: voici comment faire un ||= en Python.

def test_function(self, d=None):
    'a simple test function'
    d = d or {}

    # ... do things with d and return ...
9
Brian Hicks

Réponse précise: Non. Python ne possède pas d'opérateur intégré op capable de traduire x = x or y en x op y.

Mais c'est presque le cas. L'opérateur au niveau du bit ou égal (|=) sera fonctionne comme décrit ci-dessus si les deux opérandes sont traités comme des booléens, avec une mise en garde. (Quelle est la mise en garde? La réponse est ci-dessous bien sûr.)

Tout d’abord, la démonstration de base des fonctionnalités:

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

La mise en garde est due au fait que python n'est pas strictement typé. Ainsi, même si les valeurs sont traitées comme des booléens dans une expression, elles ne seront pas court-circuitées si elles sont transmises à un opérateur au niveau du bit. Par exemple, supposons que nous ayons une fonction booléenne qui efface une liste et renvoie True si et seulement si des éléments ont été supprimés:

def  my_clear_list(lst):
    if not lst:
        return False
    else:
        del lst[:]
        return True

Nous pouvons maintenant voir le comportement court-circuité comme suit:

x = True
lst = [1, 2, 3]
x = x or my_clear_list(lst)
print(x, lst)

Output: True [1, 2, 3]

Cependant, le passage de or à un bit ou (|) supprime le court-circuit et la fonction my_clear_list est exécutée.

x = True
lst = [1, 2, 3]
x = x | my_clear_list(lst)
print(x, lst)

Output: True []

Ci-dessus, x = x | my_clear_list(lst) est équivalent à x |= my_clear_list(lst).

5
Apollys

En général, vous pouvez utiliser dict[key] = dict.get(key, 0) + val

0
curtissv