PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

La magie des booléens en Python

vendredi 4 octobre 2013 à 12:11

Dans un langage fortement typé comme Python, on ne peut pas additionner des choux et des carottes, comme disait madame Germaine, ma prof de mate.

Photo d'une pinup déguisée en prof

J'ai toujours eu des soucis d'intégration en cours de maths. Mon attention était discontinue et je ne me sentais pas dans mon domaine.

Par exemple on ne peut pas faire ça :

>>> 1 + "1"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Nonnnnnnnn !

Ni ça :

>>> [1] + (1,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list

Pas biennnnnnnnnnnnnn !

Et pas ça :

>>> True + 1
2

OUATE ZE PHOQUE ?

Les booléens sont des entiers déguisés

Pendant longtemps, Python n’a pas eu de type bool, et on utilisait, comme en C, 0 pour faux, et 1 pour vrai. Ça marchait pas mal, mais dans un souci de rentre le langage plus propre, on a voulu créer une type spécialisé, et ainsi :

>>> type(True)
<class 'bool'>
>>> type(1)
<class 'int'>

Mais il faut avouer que pouvoir interchanger True pour 1 et False pour 0 et vice versouille, c’était achement pratique dans une discipline ou la manipulation des chiffres à des fins logiques est un peu la base du métier. Du coup il a été décidé que les booléen seraient des travs, juste une surcouche au dessus des entiers, et qu’on pourrait les utiliser en lieu et place de ceux-ci. Une exception étonnante vu la rigueur du langage sur la gestion des types.

Du coup :

>>> True == 1
True
>>> False == 0
True
>>> True + 1
2
>>> False - 1
-1

Par contre :

>>> 1 is 1
True
>>> True is True
True
>>> True is 1
False

Et qui dit exception, dit hack

Donc voici quelques moyens de détourner l’utilisation des booléens pour écrire du Perlthon…

On peut utiliser un bool pour de l’indexing ou du slicing :

>>> ('Valeur 1', 'Valeur 2')[True]
'Valeur 2'
>>> list(range(10)[True:False-1:2])
[1, 3, 5, 7]

On peut utiliser un bool pour multiplier, et l’opération multiplier marche sur les strings et les listes…

>>> "J'aime les chat" + "s" * est_pluriel
"J'aime les chat"
>>> est_pluriel = True
>>> "J'aime les chat" + "s" * est_pluriel
"J'aime les chats"
>>> def process(lst, cancel=False):
...     lst = list(lst) * (not cancel)
...     for i in lst:
...         print(i)
... 
>>> process(range(3))
0
1
2
>>> process(range(3), True)

Ou même pire, saviez-vous que la déclaration d’héritage et les clauses d’exception pouvaient inclure une expression ? En rajoutant de l’unpacking, on obtient un truc bien marrant :

>>> class Parent:
...     foo = "bar"
... 
>>> inherit = False
>>> class Enfant(*[Parent] * inherit):
...     pass
... 
>>> Enfant().foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Enfant' object has no attribute 'foo'
>>> inherit = True
>>> class Enfant(*[Parent] * inherit):
...     pass
... 
>>> Enfant().foo
'bar'
>>> catch = True
>>> try:
...     42 / 0
... except (ZeroDivisionError,) * catch:
...     print("Nope")
Nope
>>> catch = False
>>> try:
...     42 / 0
... except (ZeroDivisionError,) * catch:
...     print("Nope")
Traceback (most recent call last):
  File "<ipython-input-12-c01f7e27284d>", line 2, in <module>
    42 / 0
ZeroDivisionError: division by zero

Évidelement ça marche avec n’importe quels entiers, mais où serait le fun ?

Et on peut utiliser un bool pour incrémenter une valeur.

>>> increment = True
>>> value = 0
>>> for x in range(10):
...     value += increment
... 
>>> value
10
>>> increment = False
>>> for x in range(10):
...     value += increment
... 
>>> value
10

Voilà de quoi bien vous marrer au boulot lors de votre prochaine code review !

flattr this!

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?La-magie-des-bool%C3%A9ens-en-Python #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}