modifié le

Sous le capot

capot

Que se passe-t-il dans les entrailles de l’interpréteur Python ? Il est parfois nécessaire de le savoir, pour comprendre la logique de certains comportements qui sinon paraissent bizarres.

1. Mutabilité

1.1. Observation

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

1.2. Visualisation

exemple 1
a = "uv"
b = a
print(id(a),id(b),a is b)    # 140245667117360 140245667117360 True
str1
a += "w"             (1)
print(id(a),id(b),a is b)    # 140245667117392 140245667117360 False
1 l’instruction a+="w" ne modifie pas la donnée uv, mais en crée un nouveau uvw, et fait pointer la variable a vers cette nouvelle donnée : une chaîne de caractères est donc immuable (immutable).
str2
exemple 2
a = [1,2]
b = a
print(id(a),id(b),a is b)    # 140245663171968 140245663171968 True
list1
a += [3]           (1)
print(id(a),id(b),a is b)    # 140245663171968 140245663171968 True
1 l’instruction a+=[3] modifie la liste [1,2] : une liste est donc muable (mutable).
list2

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

1.3. Quel impact ?

Méfiance lorsque 2 variables pointent vers la même donnée

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Attention aux arguments de fonction, au retour de l’appel

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

2. Tableau associatif

Un tableau associatif, ou table de hashage, est une structure de données de haut niveau, n’existant pas forcément dans tous les langages de programmation, notamment les plus anciens (comme C). Elle est appelée dictionnaire en Python, hash en Perl, map en C++.

Un tableau associatif est un conteneur de paires (clé,valeur). Les clés sont uniques. Une valeur peut être recupérée directement à partir de la clé associée, sans itérer : par un accès direct (random access).

2.1. Complexité algorithmique

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

2.2. Recherche séquentielle et dichotomique

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

2.3. Index

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

2.4. id

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

a is b signifie id(a)==id(b).

Un id n’a de consistance que pendant la session d’exécution courante : un objet ne conserve pas son id d’une exécution à l’autre.

2.5. Hash

Le hash d’une donnée est une empreinte (digest) de cette données, un résumé (typiquement un entier). Il est improbable que 2 données distinctes produisent le même hash (improbable mais pas impossible, situation appelée collision).

Une fonction de hashage est l’agorithme qui calcule le hash sur un ensemble de données. Un bon algorithme doit essayer de distribuer uniformément les valeurs qu’il distribue, de façon à minimiser les collisions. MD, SHA, RIPEMD sont des exemples de fonctions de hashage connues. Les commandes Unix md5sum, sha1sum, sha512sum en donnent une implémentation.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

En Python, une donnée possédant un hash s’appelle un hashable. On obtient le hash d’une donnée via la fonction hash().

Question xx3.1

Déterminer, parmi les types prédéfinis (int, float, str, list, tuple, range, set, frozenset et dict), les hashables. Comment varie le hash d’une exécution à l’autre ?

Question xx3.2

Qu’en est-il des instances de classe ? Comment varie le hash d’une exécution à l’autre ? Quel impact l’état de l’objet a-t-il sur le hash ?

2.6. Implémentation d’un dictionnaire

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Seuls les données hashables peuvent être clé dans un dictionnaire. De même, et pour les mêmes raisons, seule une donnée hashable peut être élément d’un ensemble (type set et frozenset).

3. Objets

3.1. __eq__()

La méthode __eq__() donne un sens à l’expression x==y. Si la classe ne surcharge pas cette méthode, alors le comportement par défaut est x==y ⇐⇒ x is y.

3.2. __hash__()

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Les instances de classes sont hashables, mais le programmeur peut personnaliser la valeur du hash en surchargeant la méthode __hash__(). Pour cela, une contrainte à respecter impérativement est : x==y ⇒ hash(x)==hash(y).

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

4. Persistance

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

La transposition de la donnée en un format valide au-delà de son contexte natif s’appelle sérialisation.

4.1. Sérialisation

La sérialisation (serialization, flattening ou encore marshalling) est le processus par lequel des données résidant en mémoire vive sont transformées (généralement en une suite d’octets) en vue de persister hors de ce contexte.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Exemple
l1 = [ [1,2],[1,2] ]
print(f"{l1=}")            # l1=[[1,2],[1,2]]
serializ1
l3 = [1,2]
l2 = [l3,l3]
print(f"{l2=}")            # l2=[[1,2],[1,2]]
serializ2

4.2. La méthode __repr__()

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

4.3. Le module Pickle

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Le format des données contenues dans /tmp/picklefile est spécifique à Pickle. Par conséquent, l’application qui sérialise et celle qui désérialise doivent utiliser Pickle (et attention si la version de Pickle est différente !). ce qui sous-entend que ce sont 2 applications Python, Pour lever cette contrainte, il faudrait utiliser un format plus portable, un format ouvert indépendant, comme XML ou JSON.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.