La magie des opérations booléennes

J'étais persuadé qu'avec Python, les opérations booléennes x and y et x or y ne retournait que des booléens. Mais en fait, non ! Et je m'émerveille de leur fonctionnement réel ! :)

Et pourtant, j'avais déjà utilisé des syntaxes du genre x = y or 0 qui donne la valeur 0 à x si y est évalué à False, et y sinon. J'avais utilisé cette syntaxe sans savoir ce qu'il se passait derrière, et je trouvais cette syntaxe pratique. Hier, j'ai relu du code et j'ai trouvé quelque chose du genre x = y and 1 or 0. Et là, je me suis dit "Hein ?".

Voici donc l'explication : or et and évaluent la première variable et retournent l'une deux variable. x or y retourne x si x est évalué à True, et y sinon. x and y retourne y si x est évalué à True, et x sinon. Pas très clair ? Vous retrouverez le détail des explications dans la documentation officielle des opérations booléennes. Et voici quelques exemples :

>>> 1 and 'a''a' >>> 0 and 'a'0 >>> 1 or 'a'1 >>> 0 or 'a''a' >>> '' or 'a''a' >>> [] or 'a''a' >>> True and 'a''a' >>> False and 'a'False >>> True or 'a'True >>> False or 'a''a' >>>

L'évaluation d'une variable fonctionne comme la conversion en booléen : elle utilise la méthode spéciale __nonzero__ en Python 2 (doc de __nonzero__) et __bool__ en Python 3 (doc de __bool__). Si cette méthode n'est pas définie, elle regarde le retour de la méthode __len__. Et si aucune de ces deux méthodes n'est définie, alors c'est True.

Voici des exemples dans la console interactive Python 3 :

>>> class test_true:... def __bool__(self): # __nonzero__ en Python 2... return True...>>> bool(test_true())True >>> class test_false:... def __bool__(self): # __nonzero__ en Python 2... return False...>>> bool(test_false())False >>> class test_len_0:... def __len__(self):... return 0...>>> bool(test_len_0())False >>> class test_len_1:... def __len__(self):... return 1...>>> bool(test_len_1())True >>> class test_pass:... pass...>>> bool(test_pass())TrueEt la syntaxe x = y and 1 or 0, peut être décortiquée de la manière suivante :

  • si bool(y) est True alors y and 1 renvoie 1 et 1 or 0 renvoie 1.
  • si bool(y) est False, alors y and 1 renvoie y et y or 0 renvoie 0.

Et cette syntaxe correspond à l'algorithme suivant :

if y: x = 1else: x = 0

Mais x = y and 1 or 0 est bien plus court et pratique.

C'est bête, mais à chaque que je regarde un peu les entrailles de Python, je m'émerveille un peu plus ! :)

Derniers articles

Accélérer une suite de tests Django et Pytest sur un poste de développement

Au printemps 2025, j'ai râlé sur une suite de tests trop lente. Voici les diverses solutions qui ont amélioré la situation.

Django-ninja ? 🥷

Django-ninja est une librairie python, qui, comme son nom peut le laisser deviner, s’intègre avec django. À quoi ça sert ? Comment on fait ? Je vais le raconter dans cet article.

Rencontres en non-mixité choisie : retour d’expérience et mise en perspective

En 2023 et 2024, Hashbang a accueilli des rencontres réservées aux femmes et aux personnes non-binaires. Nous revenons sur ces rencontres et leurs enseignements.

Pourquoi nous utilisons Wagtail : le CMS Django qui sépare les casquettes

Une introduction à Wagtail et son Zen : comment laisser à l'éditeur·i·ce de contenu un peu de choix, mais pas trop.