0% found this document useful (0 votes)
50 views191 pages

Apprendre À Programmer en Python

Uploaded by

BETA ENTREPRISE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
50 views191 pages

Apprendre À Programmer en Python

Uploaded by

BETA ENTREPRISE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Apprendre à programmer en Python |

Par Zambou Sombefoung Lenz


Cours complet (2023)

Objectifs du cours Python:


Bienvenue dans ce cours traitant d’un des langages de programmation les plus célèbres
et les plus plébiscités : Python. Le but de ce cours est de comprendre ce qu’est Python,
ce que Python permet de réaliser et d’explorer ses différentes fonctionnalités et de vous
apprendre à les utiliser pas à pas.

L’idée de ce cours n’est pas simplement de vous présenter les différents éléments de
Python un-à-un mais véritablement de vous expliquer quand et comment utiliser chaque
nouvelle notion afin que vous ayez le plus rapidement une vue d’ensemble claire pour
utiliser les différents éléments de ce langage au bon moment et à bon escient.
Mon but, à travers ce cours, est de vous amener vers une certaine autonomie et de faire
en sorte que vous soyez capables de réaliser de petits projets Python par vous même à
la fin de celui-ci.

Prérequis pour suivre ce cours Python


Python est un langage qui a été créé pour être le plus lisible et le plus simple à
comprendre et à utiliser possible. C’est donc un bon choix pour des débutants et ce n’est
d’ailleurs pas par hasard qu’il est l’un des langages les plus recommandés aux personnes
souhaitant s’initier à la programmation.

En effet, la syntaxe de Python encourage la mise en place de nombreuses bonnes


pratiques qui vous seront utiles par la suite dans votre vie de développeur.

Ce cours est ainsi ouvert à tous : nous commencerons par nous familiariser avec
l’environnement de travail Python avant de présenter des structures simples puis irons
progressivement vers des notions plus complexes.

Méthodologie du cours Python


Dans un but pédagogique, et afin de vous fournir la meilleure expérience
d’apprentissage possible, ce cours a été divisé en de multiples sous-chapitres eux
mêmes regroupés en sections.

Chaque nouvelle section dispose d’un script illustré par de nombreux exemples. Dans ce
cours Python, nous travaillerons avec l’interpréteur Python en mode interactif, ce qui
signifie que nous taperons les différentes commandes Python directement dans l’invite
de commande ou le terminal. Je vous invite fortement à faire l’effort de recopier chacun
de mes codes vous même car c’est en pratiquant qu’on apprend le mieux et car c’est
comme cela que vous pourrez vous familiariser le plus vite avec la syntaxe Python et cela
rendra le cours beaucoup plus dynamique pour vous.

A l’inverse, je vous déconseille de « rusher » ce cours et d’essayer d’en faire le tour en


deux jours : cela ne sera pas efficace car vous ne pourrez pas apprendre à programmer
comme cela. Il faut du temps pour intégrer les différentes structures de langage et la
place et l’utilité de chacune d’entre elles.

Contenu du cours Python


Dans ce cours, nous allons nous appliquer à décomposer et à expliquer chaque notion
communément utilisée de Python. Nous allons commencer avec l’installation de
(l’interpréteur) Python et avec quelques commandes simples pour se familiariser avec
l’environnement Python.

Ensuite, nous découvrirons les variables Python, puis les types de données, les structures
de contrôles (conditions et boucles) et les fonctions Python.

Dans un troisième temps, nous nous attaquerons à ce qui fait selon moi le coeur de
Pyhon : l’orienté objet les classes, les instances et les objets.

Nous terminerons finalement avec d’autres opérations et notions qu’il faut connaitre en
Python comme la manipulation des fichiers, l’utilisation des modules , la gestion des
erreurs et un travaille diriger sur l’utilisation du module pygame pour la creation des
jeux videos.

Python est un langage de programmation créé par Guido Van Rossum. La première
version publique du langage est sortie en 1991. Son nom provient de la troupe de
comiques anglais les Monty Python.
Python est un langage interprété, qui se veut simple à comprendre, modulable et aux
applications multiples. C’est aujourd’hui un des langages les plus utilisés et les plus
plébiscités par les développeurs.

Cette première leçon a pour but de présenter le langage Python et de poser quelques
concepts fondamentaux relatifs aux langages de programmation qui nous seront utiles
par la suite.

Python, un langage de programmation


Un ordinateur est une machine dont la fonction principale est de traiter des données,
c’est-à-dire d’exécuter des séries d’instructions pour effectuer différentes tâches.

En tant que développeurs, nous allons vouloir fournir nos séries d’instructions aux
ordinateurs afin qu’ils exécutent certaines tâches précises dans un certain ordre.

Pour cela, il va falloir que l’ordinateur nous comprenne et il va donc falloir qu’on exprime
nos instructions dans un langage qu’il comprend. Le souci, ici, est que les ordinateurs ne
comprennent qu’un seul langage : le binaire ou “langage machine” qui est très opaque
pour nous (les Humains) et très long à écrire.

Pour pallier à ce problème, certaines personnes ont créé ce qu’on appelle des langages
de programmation. Le but premier de tout langage de programmation est de passer des
instructions à l’ordinateur.

Schématiquement, on utilise des langages de programmation car il est plus facile de


nous exprimer et d’expliciter nos séries d’instruction en suivant leurs conventions
d’écriture plutôt que de passer nos instructions directement en binaire à l’ordinateur.

Le langage de programmation se charge de la conversion : il reçoit nos instructions et


les transforme en binaire pour les passer à l’ordinateur afin que celui-ci les exécute.

Tous les langages de programmation ne sont pourtant pas égaux : certains sont plus
facilement compréhensibles pour nous que d’autres et certains nous permettent de
transmettre uniquement certaines instructions à l’ordinateur.

Python est un langage de programmation dit de “très haut niveau”. Cela signifie qu’il
possède un haut niveau d’abstraction par rapport au langage machine. Pour le dire très
simplement : plus un langage de programmation est de “haut niveau”, plus sa syntaxe se
rapproche de notre langage (l’anglais) plutôt que du langage machine. Un langage de
haut niveau est donc plus facile à comprendre et à utiliser qu’un langage de plus bas
niveau.

Python, un langage interprété


Comment font les langages de programmation pour transformer nos instructions en
instructions compréhensibles par un ordinateur ? Ils leur faut un traducteur. Certains
langages utilisent un interpréteur comme traducteur tandis que d’autres utilisent un
compilateur.

Un interpréteur se distingue d’un compilateur par le fait que, pour exécuter un


programme, les opérations d’analyse et de traductions sont réalisées à chaque exécution
du programme (par un interprète) plutôt qu’une fois pour toutes (par un compilateur).

L’interprétation repose sur l’exécution dynamique du programme par un autre


programme (l’interpréteur), plutôt que sur sa conversion en un autre langage (par
exemple le langage machine).

Ainsi, contrairement au compilateur, l’interpréteur exécute les instructions du


programme (ou en évalue les expressions), au fur et à mesure de leur lecture pour
interprétation. Du fait de cette phase sans traduction préalable, l’exécution d’un
programme interprété est généralement plus lente que le même programme compilé.

En revanche, les langages interprétés sont généralement plus simples à appréhender


puisqu’on ne passe pas par une étape de compilation avant d’exécuter son programme
et la portabilité.

En effet, un langage comme Python fonctionnera avec n’importe quel système


d’opération (OS) du moment que l’OS en question possède l’interpréteur Python. Un
compilateur, de l’autre côté, va produire un programme écrit en langage assembleur et
ce langage assembleur va être différent pour chaque OS. Par conséquent, les
programmes compilés ne peuvent s’exécuter que sur des ordinateurs dotés de la même
architecture que l’ordinateur sur lequel ils ont été compilés.

Python, un langage extensible et polyvalent


Python est modulable et extensible : une fois qu’on connait les bases du langage, on va
pouvoir relativement simplement ajouter de nouvelles fonctions ou modules pour
étendre les possibilités de ce langage.
Ce langage est un langage orienté objet à la base mais Python supporte également
d’autres paradigmes comme la programmation procédurale et fonctionnelle. Un
paradigme est une “façon de coder” ou une “façon d’imaginer le code et de le
structurer”. Nous reviendrons là dessus plus tard.

Un point sur les versions Python


Avant de passer à la suite, j’aimerais vous parler des différentes versions du langage
Python car, sur ce point, l’équipe de développement de Python a fait des choix
particuliers.

En informatique, les langages évoluent par “version”. Les équipes qui créent un langage
travaillent sans cesse à l’amélioration de celui-ci mais chaque changement fait sur le
langage n’est pas immédiatement intégré au langage ni disponible au public.

Au contraire, une liste de modifications / ajouts sont faits au langage en arrière plan et,
dès que l’équipe gérant l’évolution du langage juge les changements suffisamment
importants et stables, une nouvelle “version” du langage qui incorpore ces changement
est distribuée.

La première grosse mise à jour de Python date de 2000 avec la version Python 2. Les
versions se sont ensuite enchainées normalement avec Python 2.1, 2.2, 2.3, etc. jusqu’en
2009 avec la sortie de Python 3.

Pour Python 3, l’équipe qui gère l’évolution du Python a fait le choix audacieux de partir
sur de nouvelles bases et de casser la compatibilité avec les anciennes versions.

Généralement, lorsqu’un langage évolue et que de nouvelles versions paraissent, les


équipes de développement font bien attention à proposer une compatibilité ascendante,
c’est-à-dire à faire en sorte que les codes créés sous d’anciennes versions fonctionnent
toujours avec les nouvelles versions des langages. En effet, sans ce principe de
compatibilité, la plupart des programmes et des sites Web ne fonctionneraient pas
puisque les développeurs de ceux-ci devraient absolument les modifier à chaque
nouvelle version d’un langage utilisé pour coller aux nouvelles normes.
A l’inverse, le fait de proposer une comptabilité ascendante entre chaque version pose
de vrais problèmes d’héritage aux développeurs d’un langage puisque ces derniers sont
obligés de conserver certaines syntaxes et fonctionnalités totalement obsolètes.

Voulant modifier en profondeur leur langage et proposer une version beaucoup plus
“propre” et au goût du jour, la Python Software Fondations (l’équipe chargée du
développement du Python) a donc décidé de faire table rase pour Python 3 et de partir
sur de nouvelles bases.

Le souci ici est que Python 2.x était déjà très populaire à l’époque et que cela allait
mettre de nombreuses personnes dans l’embarras. L’équipe de Python a donc fait le
choix de conserver deux versions du langage : Python 2.x et Python 3.x et de les faire
évoluer de front. Pour être tout à fait précis, la version 3 est la version dont les
fonctionnalités allaient continuer d’évoluer tandis que la version 2 n’allait recevoir que
des mises à jour liées à la sécurité.

Aujourd’hui encore, on retrouve ces deux versions de Python qui co-existent. Pour nous,
cependant, le problème ne se pose pas : nous travaillerons bien évidemment avec la
dernière version en date de Python qui est à l’heure où j’écris la version 3.10.4

Python est un langage de programmation conçu dès le départ pour être “full stack”,
c’est-à-dire pour avoir de multiples applications à la différence du PHP par exemple qui
a clairement été imaginé pour fonctionner dans un contexte Web.

Dans cette leçon, nous mettons en place notre environnement de travail en nous
équipant des logiciels nécessaires pour pouvoir développer en Python.
 

Coder en Python : simple et gratuit


Python est un langage Open Source. Cela signifie que ses sources et son interpréteur
sont disponibles au public et donc que n’importe qui peut commencer à développer ses
propres programmes Python gratuitement.
Pour coder en Python, un seul programme va être strictement obligatoire : l’interpréteur
Python qui va pouvoir être utilisé de manière dynamique et nous afficher les résultats de
nos codes immédiatement.

En pratique, cependant, nous voudrons souvent enregistrer nos différents scripts dans
des fichiers plutôt que d’écrire des séries d’instructions à exécuter immédiatement. Pour
cela, nous avoir besoin d’un éditeur de texte ou d’un IDE (Environnement de Travail
Intégré).

L’interpréteur Python
Python est un langage interprété, ce qui signifie qu’on va avoir besoin d’un programme
nommé interpréteur pour convertir nos instructions Python en un langage
compréhensible par notre ordinateur.

L’interpréteur Python est disponible en téléchargement gratuit sur le site officiel du


langage, dans la rubrique téléchargement : https://www.python.org/downloads/.

Sur cette page, commencez par télécharger la dernière version stable de Python qui
correspond à votre système. L’interpréteur sera parmi les fichiers téléchargés.

Notez que si vous utilisez un Mac un interpréteur Python devrait déjà être installé sur
votre machine par défaut. Cependant, l’interpréteur pré-installé risque de correspondre à
une ancienne version et nous voulons dans ce cours travailler avec la dernière version
stable du langage (Python 3.10.4 à l’heure de ce tutoriel).

Une fois que vous avez téléchargé la ressource Python disponible sur le site officiel,
ouvrez la en double cliquant dessus. Un processus d’installation démarre. Si vous êtes
sur Windows, cochez la case “Ajouter Python 3.x au PATH”. Suivez ensuite le processus
d’installation comme pour n’importe quel autre logiciel.

Vous venez d’installer l’interpréteur Python ainsi que d’autres ressources pour vous aider
dans vos développements Python, notamment IDLE et Python Launcher si vous utilisez
un Mac.
IDLE est un environnement de développement intégré spécialement pour Python qui
nous permet d’exécuter directement du code Python. Python Launcher permet lui
d’exécuter du code Python créé dans des fichiers séparés .py en double cliquant
simplement sur ces fichiers. Ces deux logiciels sont extrêmement puissants et pratiques,
même si nous ne nous en servirons pas dans ce cours pour faciliter la compréhension et
le suivi de tous.

Pour exécuter nos scripts Python, il va falloir les passer à l’interpréteur. Pour cela, nous
aL’invite de commande se trouve dans le menu Démarrer de Windows sous le nom cmd.
Le terminal se trouve dans le dossier Applications, puis Utilitaire de Mac. Dès que vous
trouvez l’invite de commande ou le terminal, ouvrez le. Une fenêtre noire devrait
apparaitre.

Une fois que vous êtes dans l’invite de commande ou dans le terminal, commencez par
vérifier que l’interpréteur Python a bien été installé. Pour cela, tapez la commande python
-V (avec un V majuscule) et pressez la touche Entrée. Si vous êtes sur Mac, Python 2.7
devrait déjà être installé et sera probablement la version renvoyée. Tapez plutôt la
commande python3 -V. La version de l’interpréteur Python installée devrait vous être
renvoyée.

Pour appeler l’interpréteur, tapez simplement python3 (ou python3.7 dans le cas où il y


aurait une ambiguïté) (Mac) ou python (Windows). Si la version de l’interpréteur vous est
renvoyée te que vous voyez un triple chevron $gt;$gt;$gt;, c’est gagné ! Ce triple chevron
est le moyen pour l’interpréteur de nous dire “je suis prêt à recevoir la prochaine
instruction”.

utiliser l’invite de commande (Windows) ou le terminal (Mac).


A partir de là, nous avons deux options : on va pouvoir soit directement écrire nos
instructions Python dans l’invite de commande ou dans le terminal pour les exécuter
immédiatement, soit créer des fichiers de script Python avec l’extension .py avec un
éditeur de texte et les passer ensuite à l’interpréteur. Dans l’image ci-dessus, par
exemple, j’ai tapé et exécuté une première instruction Python print() qui sert simplement
à afficher un message.

Ecrire son code directement dans l’invite de commande / le terminal est très pratique
pour tester rapidement un code. Cependant, en conditions “réelles”, c’est-à-dire lorsque
vous devrez créer de vrais programmes contenant potentiellement plusieurs scripts ou
lorsque vous voudrez distribuer votre code, vous stockerez vos instructions dans des
fichiers .py que vous allez créer avec un éditeur de texte ou un IDE.

L’éditeur de texte
Si vous avez décidé de suivre ce tutoriel sur Python, je suppose que vous savez déjà ce
qu’est un éditeur de texte.

Un éditeur de texte nous permet tout simplement d’écrire des lignes de code et
d’enregistrer nos fichiers au bon format.

Il existe des centaines d’éditeur prêt à télécharger sur le Web et la majorité d’entre eux
sont gratuits. Je n’ai pas de conseil spécifique à vous donner quant au choix de votre
éditeur de texte : essayez simplement d’en trouver un avec lequel vous êtes à l’aise et si
possible installez plutôt un IDE (Environnement de Travail Intégré) qu’un simple éditeur.

Les IDE disposent de fonctionnalités supplémentaires comme des mécanismes d’auto-


complétion du code ou encore de systèmes de détection des erreurs de syntaxe dans un
code et de proposition de modification.

Pour ma part, dans ce cours, j’utiliserai l’IDE Visual Studio Code de Microsoft mais vous
pouvez utiliser Brackets, Atom, Sublime Text ou encore Komodo si vous préférez.

Notez par ailleurs qu’il existe certains éditeurs spécialement conçus pour écrire du code
Python dont le célèbre PyCharm notamment .
Syntaxe de base et exécution
d’instructions Python

Dans cette leçon, nous allons découvrir quelques éléments de syntaxe de base de
Python. Nous allons également exécuter nos première instructions Python en utilisant
l’interpréteur de manière interactive ou en créant un fichier Python qu’on va ensuite
passer à l’interpréteur.
 

Créer un fichier Python


Nous avons deux choix pour exécuter du code Python : on peut soit écrire directement
notre code dans l’invite de commande (Windows) ou dans le terminal (Mac) afin que
l’interpréteur Python interprète directement notre code et nous renvoie son résultat ou
on peut créer des fichiers Python avec un ensemble d’instructions à l’intérieur et qu’on
va ensuite passer à l’interpréteur.

L’intérêt principal d’un fichier est qu’il peut être sauvegardé et distribué. En conditions
réelles, vous utiliserez donc souvent votre éditeur de texte et créerez des fichiers Python
pour mener à bien des projets.

Dans ce cours, j’écrirai directement dans mon terminal pour vous montrer les résultats
d’instructions simples et nous ne créerons des fichiers que lorsque cela sera nécessaire.
Cependant, pour cette première leçon concrète, je voulais tout de même vous montrer
comment créer un fichier Python et comment exécuter ce fichier.

Pour créer un fichier Python, nous allons déjà ouvrir notre éditeur de texte, allons ouvrir
un nouveau fichier et enregistrer ce fichier en lui donnant une extension .py. On peut
appeler ce fichier cours.py par exemple et l’enregistrer dans un dossier Python sur notre
bureau.
Ici, on commence par enregistrer notre fichier au format Python avant même d’écrire un
quelconque code car cela va permettre à notre éditeur de reconnaitre le type de code
qu’on souhaite écrire et d nous proposer des fonctionnalités relatives à cela. Par ailleurs,
il est possible que votre éditeur vous propose d’installer des extensions spécifiques
Python pour faciliter l’écriture, l’affichage et le debugging de votre code. Si c’est le cas,
n’hésitez pas à les installer.

Ensuite, ajoutez les lignes de code suivantes dans votre fichier (nous allons expliquer par
la suite ce qu’elles signifient) :

Exécuter un fichier Python


Pour exécuter un fichier Python et obtenir le résultat des opérations faites dans ce
fichier, commencez déjà par ouvrir votre invite de commande ou votre terminal.

Ici, si vous avez bien ajouté Python au PATH, vous n’avez qu’à taper cours.py pour
exécuter le code du fichier “cours.py”. Si votre système possède plusieurs versions de
Python, comme c’est le cas sur Mac, il faudra préciser la version utilisée : on tapera
alors python3 cours.py.
Si Python n’a pas été ajouté au PATH, il va falloir préciser où le fichier se trouve. Pour
cela, on va commencer par taper la commande cd Desktop. La commande cd signifie
“change directory” (“changer de dossier”).

Ensuite, on n’a plus qu’à préciser l’emplacement de notre fichier par rapport à notre
bureau (Desktop), c’est à dire dans notre cas Python/cours.py (Mac) ou Python\
cours.py (Windows) pour exécuter notre fichier, en précisant éventuellement également
une version si plusieurs versions sont installées sur notre système ( python3
Python/cours.py pour Mac).

Exécuter du Python en tapant directement


dans l’invite de commande ou le terminal
L’interpréteur Python peut être utilisé de manière interactive, c’est-à-dire qu’on va
pouvoir directement lui fournir du code Python à exécuter et il nous renverra les
résultats immédiatement.

Cette fonctionnalité est très utile lorsqu’on souhaite tester rapidement des bouts de
code ou pour l’apprentissage.

Pour utiliser l’interpréteur Python de cette manière, on va déjà devoir l’appeler depuis
l’invite de commande ou le terminal. Pour cela, on écrit la commande Python3.7 et on
presse Entrée pour valider.
Ensuite, on a plus qu’à écrire nos différentes instructions et à presser Entrée afin que
l’interpréteur les interprète immédiatement.

Syntaxe de base de Python : indentation,


commentaires et print()
Chaque langage informatique est basé sur une série de règles et de conventions. La
syntaxe d’un langage définit ses différents éléments et la façon dont on va pouvoir et
devoir les utiliser.
J’aimerais pour le moment m’arrêter sur deux éléments de syntaxe de base que sont les
commentaires et l’indentation ainsi que sur la fonction print().

Les commentaires Python


Les commentaires sont des éléments de langage qu’on retrouve dans de nombreux
langages de programmation.

Les commentaires servent à “commenter” le code : ils vont être ignorés lors de
l’exécution du code (ils n’auront aucun impact sur le script) et vont donc être totalement
transparents pour l’utilisateur final.

On utilise généralement les commentaires pour documenter un code (pour soi ou pour
d’autres développeurs si le code a vocation à être distribué) ou pour empêcher son
exécution. En Python, on utilise le signe # pour écrire un commentaire dans notre code.

Python n’a pas de syntaxe particulière pour écrire des commentaires multi-lignes. Pour
écrire un commentaire sur plusieurs lignes, on insérera un # au début de chaque ligne.

L’indentation Python
L’indentation correspond au fait de créer des retraits au niveau de certaines lignes de
code. Dans la grande majorité des langages, l’indentation n’a qu’une visée esthétique :
elle permet à un script d’être plus lisible pour un développeur.

Généralement, une bonne indentation est censée représenter les dépendances au sein
d’un code : on ajoutera un retrait à chaque fois qu’une instruction est incluse / dépend
d’une autre.

En Python, l’indentation a un tout autre rôle : elle est utilisée par Python pour définir des
blocs de code, c’est-à-dire pour indiquer à l’interpréteur quelle instruction appartient à
quelle autre.

Si on indente mal notre code Python, celui-ci ne s’exécutera tout simplement pas et
Python renverra une erreur. Pas de panique, nous allons apprendre au cours de ce cours
à quelle moment indenter. Cela est cependant relativement évident et ne devrait pas
vous poser de problème : dès qu’il y a une relation de dépendance, il faudra ajouter un
retrait (une fabulation).
Dans le code ci-dessus, par exemple, nous avons utilisé une structure conditionnelle if.
Le principe de cette structure est simple : on lui fournit un test et SI le test est validé,
alors on exécute un code. Le code à exécuter dépend du résultat du test; on effectuera
donc un retrait pour mentionner ce code afin que Python puisse bien s’apercevoir qu’il
dépend de la structure conditionnelle.

Si vous avez l’habitude d’autres langages de programmation comme le PHP par exemple
cela peut être un peu déconcertant au départ. Vous pouvez alors considérer que
l’indentation remplace l’usage des accolades.

La fonction print ()
Les fonctions sont d’autres éléments de langage que nous étudierons plus tard. Grosso-
modo, une fonction est définie par un nom et une série d’instructions. Lorsqu’on appelle
une fonction (en utilisant son nom et un couple de parenthèses juste derrière), elle
exécute toutes les instructions qu’elle contient. Les fonctions servent généralement à
effectuer une action précise qui peut être plus ou moins complexe.

La fonction print() permet tout simplement d’afficher le message qu’on va lui passer


entre ses parenthèses. A première vue, la fonction print() ne parait pas très utile, et c’est
pourtant l’une des fonctions qu’on utilisera le plus.

En effet, cette fonction va être très précieuse puisqu’elle va également nous permettre
d’afficher des résultats auquel on n’a pas directement accès. Nous illustrerons cela dans
la suite de ce cours; faites moi confiance pour le moment.

Les variables Python


Dans cette leçon, nous allons découvrir un élément fondamental des langages de
programmation : les variable. Nous allons expliquer ce que sont les variables en
informatique, les usages qu’on va pouvoir en faire et comment créer des variables
Python.
 

Qu’est-ce qu’une variable ?


Une variable, dans le domaine de la programmation informatique, est un conteneur qui
sert à stocker une valeur. Les variables possèdent deux caractéristiques fondamentales :
 Les variables ont une durée de vie limitée (une variable ne vit généralement que
le temps de l’exécution d’un script ou de la fonction qui l’a définie), ce qui signifie
qu’on ne va pas pouvoir utiliser les variables pour stocker des données de
manière pérenne ;
 La valeur d’une variable peut varier : les variables peuvent peuvent stocker
différentes valeurs au cours de leur vie (la nouvelle valeur remplaçant l’ancienne).
Les variables donc être au coeur de nos scripts puisqu’elles vont nous permettre de
conserver des valeurs le temps d’un script et d’effectuer toutes sortes de manipulations
sur ces valeurs en toute simplicité.

Comment déclarer une variable en Python ?


Python ne possède pas de syntaxe particulière pour créer ou “déclarer” une variable : les
variables Python sont automatiquement créées au moment où on leur assigne une
valeur.

Pour créer une variable en Python, on va donc devoir choisir un nom et affecter une
valeur à ce nom, c’est-à-dire stocker une valeur dans notre variable.

Le choix du nom pour nos variables est libre en Python. Il faut cependant respecter les
règles usuelles suivantes :

 Le nom doit commencer par une lettre ou par un underscore ;


 Le nom d’une variable ne doit contenir que des caractères alphanumériques
courants (pas d’espace dans le nom d’une variable si de caractères spéciaux
comme des caractères accentués ou tout autre signe) ;
 On ne peut pas utiliser certains mots qui possèdent déjà une signification spéciale
pour le langage (on parle de mots “réservés”).
Notez que les noms de variables en Python sont sensibles à la casse, ce qui signifie
qu’on va faire une différence entre l’emploi de majuscules et de minuscules : un même
nom écrit en majuscules ou en minuscules créera deux variables totalement différentes.

Pour affecter ou “assigner” une valeur à une variable, nous allons utiliser un opérateur
qu’on appelle opérateur d’affectation ou d’assignation et qui est représenté par le
signe =. Attention, le signe = ne signifie pas en informatique l’égalité d’un point de vue
mathématique : c’est un opérateur d’affectation.
Le signe = ne sert pas à dire que la valeur est égale au nom de variable ou que la
variable “vaut” cette valeur, il indique simplement qu’on affecte ou qu’on stocke une
certaine valeur dans un conteneur.

D’un point de vue mathématique, par exemple, écrire x = x + 2 n’a aucun sens car la
variable x ne peut être égale qu’à elle même. En informatique, cependant, c’est tout à
fait possible puisque l’opérateur = n’est pas un opérateur d’égalité mais d’affectation.
Ecrire x = x + 2 signifie qu’on affecte une nouvelle valeur à x qui est égale à l’ancienne
valeur de x à laquelle on ajoute 2.

Notez déjà qu’on va également pouvoir effectuer des affectations multiples en Python,
c’est-à-dire affecter plusieurs valeurs à plusieurs variables très facilement en utilisant la
syntaxe nom_variable_1, nom_variable_2, nom_variable_3 = valeur1, valeur2, valeur3 .

Que peut stocker une variable Python ?


Les variables vont pouvoir stocker différents types de valeurs comme des nombres, des
chaines de caractères, des booléens, et plus encore.

Il est important de connaitre le type de valeur stocké dans une variable car nous n’allons
pas pouvoir effectuer les même opérations avec une variable qui stocke un nombre ou
avec une variable qui stocke une chaine de caractères par exemple.

Nous étudierons les spécificités liées à chaque type de valeur que peut stocker une
variable Python dans la prochaine leçon.

 
Afficher et modifier le contenu d’une
variable Python
Nous allons pouvoir réaliser toutes sortes d’opérations avec nos variables. La plus
basique d’entre elles consiste à afficher le contenu d’une variable. Pour afficher la valeur
d’une variable Python, il suffit d’écrire son nom, ou éventuellement d’utiliser la
fonction print() en renseignant le nom de la variable entre les parenthèses/
Comme je l’ai précisé plus haut, l’une des caractéristiques fondamentales des variables
va être de pouvoir stocker différentes valeurs durant sa vie. Ainsi, on peut tout à fait
affecter une nouvelle valeur à une variable. Une variable « classique » ne va pouvoir
stocker qu’une valeur à la fois. En affectant une nouvelle valeur à une variable, la valeur
précédente est ainsi écrasée.

Pour comprendre ce code, vous devez savoir qu’ici les instructions sont exécutées
linéairement, c’est-à-dire dans leur ordre d’écriture. On commence par affecter la valeur
29 à notre variable age et la valeur Pierre à notre variable prenom, puis on affiche le
contenu de ces variables.

On affecte ensuite de nouvelles valeurs dans nos variables. Ces nouvelles valeurs
remplacent (“écrasent”) les précédentes. Lorsqu’on affiche à nouveau le contenu de nos
variables, les valeurs renvoyées sont les dernières stockées.

Quelle est l’utilité des variables Python ?


Les variables sont des éléments de base présents dans la quasi-totalité des langages de
programmation car elles vont s’avérer indispensables dans de très nombreuses
situations.
Il est difficile à ce niveau du cours d’illustrer concrètement la puissance des variables. Le
grand intérêt des variables va résider dans le fait qu’on va disposer d’un nom fixe (un
“label”) qui va nous servir à manipuler des valeurs qui peuvent changer ou qu’on peut ne
pas encore connaitre.

Imaginons par exemple qu’on crée un programme qui va effectuer des calculs à partir
d’une valeur qui va lui être envoyée uniquement lorsque ce programme sera exécuté.
Lors de la création du programme, on ne connait pas cette valeur et cette valeur va
pouvoir être différente entre différentes exécutions du programme.

On va pouvoir indiquer que cette valeur (inconnue pour le moment) devra être stockée
dans telle variable au début du programme et ensuite définir les différentes opérations
qui devront être effectuées sur cette valeur en utilisant le nom de la variable (qui sera
remplacée par sa valeur effective lorsque le programme s’exécutera).

Les types de données ou types de


valeurs Python
Dans cette leçon, nous allons définir ce qu’est un type de données et passer en revue les
types de données Python les plus courants et simples à appréhender.
 

Qu’est-ce qu’un type de données ?


En programmation, les données qu’on va pouvoir manipuler avec un langage sont
généralement classées par “type”.

Un “type” de données pour un langage est défini par les manipulations qu’on va pouvoir
faire sur ces données : on va pouvoir effectuer les mêmes opérations sur chaque donnée
d’un même type et des opérations différentes sur différents types de données.

Prenons un nombre entier par exemple. Il semble tout à fait logique de pouvoir effectuer
des opérations mathématiques de base avec ce nombre : addition, soustraction,
multiplication, etc. En revanche, on ne va pas pouvoir effectuer les mêmes opérations /
manipulations sur un texte, puisque multiplier un texte par quelque chose par exemple
n’a aucun sens.

 
Les types de données Python
Python définit de nombreux types de données qu’on va pouvoir stocker dans nos
variables et manipuler à loisir ensuite : nombres entiers, décimaux, complexes, chaines
de caractères, booléens, listes, tuples, dictionnaires, etc.

Dans cette leçon, nous allons nous contenter de passer en revue les types de données
les plus simples à se représenter (nombres, chaines et booléens). Les autres types de
données feront l’objet de leçons séparées.

Les types numériques int, float et complex


Python définit trois types de valeurs numériques supportées :

 Le type int qui représente tout entier positif ou négatif ;


 Le type float qui représente les nombres décimaux et certaines expressions
scientifiques comme le e pour désigner une exponentielle par exemple;
 Le type complex qui représente les nombres complexes ou nombres imaginaires et
qui se sert de la lettre j pour représenter la partie imaginaire d’un nombre.
Le type de données “nombre entier” ou int pour être technique (“int” = “integer” =
entier) couvre tous les nombres entiers positifs ou négatifs. On va pouvoir effectuer
toutes sortes d’opérations arithmétiques avec ce premier type de données : addition,
soustraction, multiplication, division, élévation à la puissance, etc.

Pour effectuer des opérations arithmétiques entre différentes valeurs numérique, nous
allons devoir utiliser des opérateurs arithmétique (+ pour l’addition, - pour la
soustraction, etc.).

On va pouvoir effectuer ces opérations directement entre nombres et se servir de Python


comme d’une calculatrice ou affecter ces nombres à des variables et utiliser nos variables
pour effectuer nos opérations :
Ici, on commence par effectuer des opérations entre nombres : addition, soustraction,
multiplication, division et élévation à la puissance. Notez que pour réaliser une division
entière, on utilise l’opérateur //. On peut également utiliser l’opérateur / pour réaliser une
division “classique” mais dans ce cas le résultat sera toujours considéré comme étant de
type float (nombre décimal). Finalement, on utilise l’opérateur ** pour élever un nombre
à la puissance.

On peut également stocker des nombres dans des variables et utiliser ces variables pour
effectuer nos calculs. Ici, on commence par définir une variable x et on lui attribue la
valeur 5. On effectue ensuite différentes opérations. Notez que durant tous ces
calculs x continue de stocker 5 puisqu’on n’affecte jamais de nouvelles valeurs à x.
Finalement, on définit une deuxième variable y = 10 et on demande à Python de
calculer x + y, c’est-à-dire de nous donner le résultat de l’addition des deux valeurs
contenues dans x et dans y.

Le type de données “nombre décimal” ou float couvre tous les nombres décimaux (c’est-
à-dire les nombres à virgule) ainsi que certaines expressions scientifiques comme le e qui
désigne une exponentielle.

Attention ici : dans le monde de la programmation, les notations anglo-saxonnes sont la


norme. Il faudra donc bien faire attention à utiliser un . et non pas une , pour les
décimaux.

Nous allons grosso-modo pouvoir réaliser les mêmes opérations avec des données de
type float qu’avec des données de type int (même si le traitement en arrière plan va être
différent).

Il y a différentes choses à noter par rapport au type float en Python :

 Toute opération arithmétique entre nombres de type float donne un résultat de


type float ;
 Toute opération arithmétique entre nombres de types int et float donne un
résultat de type float ;
 La division classique donne toujours un résultat de type float.
On effectue plusieurs opérations arithmétiques d’un coup sur nos dernières lignes dans
l’exemple ci-dessus. Dans ce cas là, il faudra faire attention à l’ordre des opérations.
L’ordre des opérations va être le même qu’en mathématiques : les calculs de puissance
seront effectués en priorité, puis la multiplication et la division, puis enfin l’addition et la
soustraction.

On va également pouvoir utiliser des parenthèses pour imposer un ordre de priorité de


calculs différents. Dans ce cas là, ce qui se trouve entre parenthèses sera calculé en
premier.

Finalement, le type de données “nombre complexe” ou complex représente les nombres


complexes. On va utiliser la lettre j ou J pour représenter la partie complexe d’un
nombre. Comme la plupart d’entre vous n’auront que rarement affaire aux nombres
complexes et que ce cours n’est pas un cours de mathématiques, je n’entrerai pas dans
le détail ici.
Le type str ou chaine de caractères
Les chaines de caractères sont ce qu’on appelle communément du texte. Pour définir
une chaine de caractères ou pour stocker une chaine de caractères dans une variable, il
faudra l’entourer de guillemets simples ou doubles droits.

Si notre chaine de caractères contient elle même des guillemets simples (apostrophes)
ou doubles, il faudra les échapper les uns ou les autres en fonction du délimiteur choisi
pour qu’ils soient correctement interprétés car sinon Python pensera qu’ils servent à
indiquer la fin de la chaine. Le caractère d’échappement en Python est l’antislash \.
Dans l’exemple ci-dessus, on veut afficher et stocker la chaine Je m’appelle “Pierre
Giraud” qui contient à la fois des guillemets simples ou apostrophes et des guillemets
doubles. Il va donc falloir qu’on échappe les uns ou les autres en fonction du caractère
de délimitation de chaine choisi afin d’indiquer au Python que les guillemets simples ou
doubles à l’intérieur de notre chaine ne représentent pas la fin de la chaine, c’est-à-dire
pour lui indiquer qu’ils ne possèdent pas ce sens spécial de délimiteurs.

Notez qu’on peut également utiliser une syntaxe alternative utilisant des triples
guillemets simples ou doubles pour entourer notre chaine et qui nous dispense ainsi
d’avoir à échapper les apostrophes et les guillemets dans notre chaine :
Lorsqu’on utilise l’interpréteur en mode interactif, comme on le fait dans ce cours,
l’interpréteur affiche les chaines entre guillemets simples. On peut utiliser la
fonction print() pour afficher les chaînes de manière plus lisible, en retirant notamment
les guillemets simples et doubles :

J’ai dit plus haut que pour définir une chaine de caractères il fallait l’entourer de
guillemets simples ou doubles droits. Réciproquement, toute valeur entourée par des
guillemets simples ou doubles sera considéré par Python comme une valeur de
type str (“str” = “string” = chaine de caractères).

Ainsi, si on stocke un ou plusieurs caractères représentant des chiffres comme “1”, “2”,
“123”, etc. en les entourant de guillemets simples ou doubles ceux-ci seront considérés
comme des valeurs de type str et non comme des valeurs de type int, code>float
ou complexe et on ne pourra pas effectuer les mêmes opérations.
Comme vous pouvez le voir, on n’obtient pas du tout les mêmes résultats lorsqu’on
additionne deux nombres ou lorsqu’on additionne (ou plus exactement concatène) deux
chaines.

Lorsqu’il est utilisé avec deux chaines, l’opérateur + est un opérateur de concaténation et


pas d’addition. “Concaténer” signifie “mettre bout à bout”. Nous reparlerons de ce
concept dans la prochaine leçon.

Finalement, vous pouvez également remarquer que Python nous renvoie une erreur
lorsqu’on tente d’additionner / de concaténer un entier avec une chaine.

Le type de valeurs bool ou booléen


Le dernier type de valeurs simple Python que je tenais à vous présenter est le
type bool (pour “booléen”).
Le type de valeur booléen est un type qui ne contient que deux valeurs qui servent à
représenter deux états. Les deux valeurs sont True (vrai) et False (faux). Attention en
Python à bien indiquer des majuscules car dans le cas contraire Python ne reconnaitra
pas ces booléens.

Pour stocker un booléen dans une variable, il ne faut pas utiliser de guillemets : si on les
utilise, ce seront les chaines de caractères “True” et “False” qui seront stockés et on ne va
pas pouvoir effectuer les mêmes opérations.

Les valeurs booléennes sont très utilisées en informatique. Elles sont notamment très
utiles pour valider ou invalider un test et sont au coeur des différentes structures de
contrôle en général.

Utiliser la fonction type() pour connaitre le


type d’une valeur
On voudra souvent s’assurer qu’une variable contient bien une valeur d’un certain type,
notamment pour pouvoir effectuer différentes manipulations avec cette variable.

Pour connaitre le type de valeur stockée dans une variable, on peut utiliser la fonction
Python type(). On va passer la variable à tester en argument de cette fonction (c’est-à-
dire écrire le nom de la variable entre les parenthèses de la fonction). La
fonction type() va alors tester la valeur contenue dans la variable et renvoyer le type de
cette valeur.
Ne faites pas attention pour le moment à l’indication “class” également renvoyée par la
fonction type(), nous verrons ce que ça signifie bien plus tard dans ce cours.

Les opérateurs Python


Dans cette nouvelle leçon, nous allons définir ce qu’est un opérateur, établir la liste des
types d’opérateurs disponibles en Python et apprendre à en manipuler certains.
 

Définition et liste des opérateurs Python


Un opérateur est un signe ou un symbole qui va nous permettre de réaliser une
opération. Le signe = par exemple est en Python l’opérateur d’affectation simple : il
permet d’affecter une valeur à une variable.
Python dispose de nombreux opérateurs qui peuvent être classés selon les catégories
suivantes :

Les opérateurs arithmétiques ;



 Les opérateurs d’affectation ou d’assignation ;
 Les opérateurs de chaines ;
 Les opérateurs de comparaison ;
 Les opérateurs logiques ;
 Les opérateurs d’identité ;
 Les opérateurs d’appartenance ;
 Les opérateurs binaires.
Dans cette leçon, nous allons nous concentrer sur les opérateurs arithmétiques, les
opérateurs de chaines et sur les opérateurs d’affectation.

Nous étudierons les autres types d’opérateurs plus tard dans ce cours, lorsque nous en
aurons besoin pour illustrer certaines notions de Python.

Les opérateurs arithmétiques


Les opérateurs arithmétiques sont utilisés pour effectuer des opérations mathématiques
comme des additions, soustractions, multiplication, etc. entre différentes variables
contenant des valeurs numériques.

Python reconnait et accepte les opérateurs arithmétiques suivants :

Opérateur Nom

+ Addition

– Soustraction

* Multiplication
Opérateur Nom

/ Division

% Modulo

** Puissance

// Division entière

Certains opérateurs nécessitent certainement qu’on s’attarde dessus.

Le modulo correspond au reste d’une division Euclidienne (division entière) tandis que
l’opérateur // permet d’obtenir le résultat entier d’une division (ou la partie entière de ce
résultat pour être tout à fait exact).

Le résultat de 13//3, par exemple, sera 4 tandis que le résultat de 13%3 sera 1 car dans le
cas d’une division entière 13/3 = 4 avec reste = 1.

L’opérateur puissance permet d’élever le nombre à gauche de l’opérateur à une certaine


puissance mentionnée à droite de l’opérateur. La “puissance” correspond à la
multiplication d’un nombre par lui même. Par exemple, écrire 2 ** 4 correspond à
multiplier 2 par lui-même 4 fois ( = 2 * 2 * 2 * 2 = 16).
 

Les opérateurs de chaines


Les opérateurs de chaines vont nous permettre de manipuler des données de
type str (chaines de caractères) et par extension des variables stockant des données de
ce type.

Python met à notre disposition deux opérateurs de chaine : l’opérateur de


concaténation + et l’opérateur de répétition *.

L’opérateur de concaténation va nous permettre de mettre bout à bout deux chaines de


caractères afin d’en former une troisième, nouvelle.

L’opérateur de répétition va nous permettre de répéter une chaine un certain nombre de


fois.

Ces deux symboles remplissent donc un rôle relativement similaire que lorsqu’ils sont
utilisés avec des données de type numériques mais attention tout de même de ne pas
confondre le + utilisé pour additionner deux nombres et le + utilisé pour concaténer
deux chaines de caractères : on distingue ici bien deux opérateurs différents même si le
même symbole est utilisé.

Les opérateurs d’affection simple et


composés Python
Nous connaissons déjà bien l’opérateur d’affectation simple Python =. Cet opérateur
permet d’affecter ou d’assigner une valeur à une variable.

Python reconnait également des opérateurs d’affectation qu’on appelle “composés” et


qui vont nous permettre d’effectuer deux opérations à la suite : une première opération
de calcul suivie immédiatement d’une opération d’affectation.
Ces opérateurs vont donc nous permettre de réduire la taille de notre code en nous
offrant une écriture simplifiée. Voici la liste des opérateurs d’affectation supportés par
Python et leur équivalent en “version longue” :

Equivalent
Opérateur Exemple Description
à

= x=1 x=1 Affecte 1 à la variable x

Ajoute 1 à la dernière valeur connue de x et


+= x += 1 x=x+1
affecte la nouvelle valeur (l’ancienne + 1) à x

Enlève 1 à la dernière valeur connue de x et


-= x -= 1 x=x–1
affecte la nouvelle valeur à x

Mutliplie par 2 la dernière valeur connue de x et


*= x *= 2 x=x*2
affecte la nouvelle valeur à x

Divise par 2 la dernière valeur connue de x et


/= x /= 2 x=x/2
affecte la nouvelle valeur à x

Calcule le reste de la division entière de x par 2 et


%= x %= 2 x=x%2
affecte ce reste à x

Calcule le résultat entier de la division de x par 2


//= x //= 2 x = x // 2
et affecte ce résultat à x

Elève x à la puissance 4 et affecte la nouvelle


**= x **= 4 x = x ** 4
valeur dans x

Vous pouvez également déjà noter qu’il existe également les opérateurs d’affectation
combinés &=, |=, ^=, >>= et <<= qui vont permettre d’effectuer des opérations dont nous
discuterons plus tard et d’affecter le résultat de ces opérations directement à une
variable.

Entrainons nous immédiatement avec ces opérateurs pour commencer à se familiariser


avec eux :

Les listes Python

Dans cette leçon, nous allons découvrir un premier type de données composites Python :
les listes. Nous allons comprendre l’intérêt de ce type de données et apprendre à les
manipuler.
 

Présentation des listes Python


Jusqu’à présent, nous n’avons stocké qu’une seule valeur à la fois dans nos variables. Les
listes sont un type de données très particulier au sens où elles représentent des données
composées ou combinées. Une liste est en effet par définition composée d’une suite de
valeur ou d’éléments. 
Pour définir une nouvelle liste en Python, on va devoir utiliser une paire de crochets [ ].
Nous allons placer les différents éléments de notre liste dans ces crochets en les
séparant par des virgules. On peut par exemple créer une liste de 5 éléments et la placer
dans une variable liste comme ceci :

Notre liste est ici composée de 5 valeurs de type numérique. On va pouvoir stocker tous
types de valeurs dans une liste, comme des chaines de caractères par exemple :

De plus, vous devez savoir que tous les éléments d’une liste n’ont pas à être du même
type, on va très bien pouvoir créer des listes composées de nombres, chaines et
booléens par exemple :

Note : Si vous avez déjà étudié un langage de script par le passé, les liste doivent vous
faire penser à ce qu’on appelle communément dans ces autres langages des tableaux. En
effet, les listes Python sont très proches des tableaux (numérotés) qu’on peut retrouver
dans de nombreux autres langages.

Récupérer une ou plusieurs valeurs dans


une liste
Les listes Python sont par défaut indexées ou indicées. Cela signifie que chaque valeur
d’une liste est lié à un indice qu’on va pouvoir utiliser pour récupérer cette valeur en
particulier.

Les listes possèdent des indices numériques qui commencent à 0. La première valeur
d’une liste possède donc toujours l’indice 0, la deuxième valeur l’indice 1, la troisième
valeur l’indice 2 et etc.

Pour récupérer une valeur en particulier dans une liste, on va devoir préciser le nom de
la liste suivi de l’indice de cette valeur entre crochets. Notez que les indices négatifs sont
acceptés; dans ce cas on partira de la fin de la liste (l’indice -1 correspond au dernier
élément, -2 à l’avant dernier et etc.).

On va également pouvoir récupérer une tranche de valeurs dans une liste, c’est-à-dire un
ensemble de valeurs qui se suivent. Pour cela, on utilisera le symbole : entre les crochets
avec 0, 1 ou 2 indices autour.

Si on utilise : sans indice, alors une copie superficielle de la liste sera renvoyée. Si on


mentionne un indice avant : mais pas d’indice après, alors une copie superficielle
partielle de la liste de départ sera renvoyée, en commençant à copier à partir de l’indice
donné. Si au contraire on mentionne un indice après : mais pas d’indice avant, une copie
superficielle partielle de la liste de départ sera renvoyée qui commence au début de la
liste et jusqu’à l’indice donné. Enfin, si deux indice sont mentionnés de part et d’autre
de :, la tranche de valeurs correspondant à ces indices sera renvoyée.
Vous devez également savoir que ce qu’on a vu jusqu’ici sur les listes s’applique
également aux chaines de caractères. Les chaînes de caractères peuvent en effet
également être indexées, ce qui signifie qu’on peut accéder aux caractères par leur
position). Cela est logique après tout : les chaines de caractères sont des “séquences” de
caractères tandis que les listes sont des “séquences” de valeurs.

Comme pour les listes, le premier caractère d’une chaîne possède l’indice 0, le deuxième
l’indice 1 et etc; On va également pouvoir utiliser des indices négatifs et récupérer des
tranches avec :.
Notez qu’il n’existe pas de type distinct pour les caractères en Python : un caractère est
simplement une chaîne de longueur 1.

Ajouter, supprimer, modifier des éléments


d’une liste
A la différence des types de données simples comme les chaines qui sont immuables, les
listes sont un type de données altérable ce qui signifie qu’on va pouvoir altérer leur
structure ou modifier leur contenu en ajoutant, supprimant ou remplaçant des valeurs.

En effet, vous devez bien comprendre qu’une fois qu’on définit une valeur “chaine de
caractères” par exemple, celle-ci ne peut plus être modifiée par la suite. Les seules
opération qu’on va pouvoir faire vont être de créer une nouvelle chaine en concaténant
deux chaines d’origine (qui une nouvelle fois ne seront pas modifiées) ou de remplacer
une chaine par une autre valeur en affectant une nouvelle valeur dans une variable (ce
qui a pour effet d’écraser la chaine de départ).

Au contraire des chaines, on va tout à fait pouvoir ajouter, modifier ou supprimer des
valeurs dans une liste. Pour cela, on va mentionner le nom de notre liste avec l’indice de
la ou des éléments à ajouter / modifier et leur affecter une nouvelle valeur. Les
affectations de tranches sont possibles :

Dans cette leçon, nous allons nous intéresser à un nouveau type de données composites
Python qui peut faire penser aux listes à premières vue : les tuples. Nous allons souligner
les différences entre les listes et les tuples, voir les cas d’usage des tuples et apprendre à
créer des tuples.
 

Présentation des tuples et cas d’utilisation


Les chaines de caractères et les listes sont deux types séquentiels de données : ce sont
des données qui sont organisées sous la forme de séquence de caractères ou de valeurs.
Les tuples sont un autre type séquentiel de données.
Les tuples ressemblent aux listes : un tuple consiste en différentes valeurs entourées par
des virgules. Notez qu’on encadre généralement les valeurs d’un tuple avec un couple
de parenthèses même si cela n’est pas obligatoire.

Les tuples peuvent contenir différents types de valeurs comme des nombres, des
chaines, des listes etc. et même d’autres tuples imbriqués. Illustrons immédiatement cela
:

La grande différence entre un tuple et une liste est qu’un tuple est une donnée
immuable à la différence d’une liste qui est altérable. Cela signifie qu’on ne va pas
pouvoir modifier les valeurs d’un tuple après sa création.

Il va donc être intéressant d’utiliser des tuples plutôt que des listes dans les cas où on
veut s’assurer que les données ne soient pas modifiées dans un programme.

Création d’un tuple vide ou à une valeur


Notez que dans le cas où on souhaite créer un tuple vide, on utilisera une paire de
parenthèses vides. Si on souhaite créer un tuple avec une seule valeur, alors il faudra
faire suivre cette valeur d’une virgule.

Le déballage de séquence
Une fonctionnalité intéressante des tuples est le “déballage de séquence”. Un déballage
de séquence correspond à une façon rapide d’affecter les différentes valeurs d’un tuple
dans des variables séparées. Pour cela, il va nous falloir autant de variables qu’il y a de
valeurs dans notre tuple. Ensuite, il va falloir respecter la syntaxe variable1, variable2 … =
tuple comme ceci :

Attention ici : il faut bien faire attention à écrire les variables qui vont recevoir les valeurs
du tuple avant le tuple car dans le cas contraire cela ne fonctionnerait pas.
Les dictionnaires Python
Dans cette leçon, nous allons nous intéresser à un autre type de données Python
composites : les dictionnaires. Nous allons découvrir l’intérêt des dictionnaires et
apprendre à manipuler ce nouveau type de données.
 

Présentation des dictionnaires Python


Les dictionnaires sont un type natif de données Python. Ce type de données peut, de la
même façon que les données séquentielles, contenir plusieurs valeurs et chaque valeur
va être indexée ce qui signifie qu’un indice unique va être attribué à chaque valeur.

La grande différence entre les données séquentielles et les dictionnaires se situe dans la
façon d’indexer les valeurs et dans la nature de l’index. Dans le cas des séquences, les
différentes valeurs dont associées à des index numériques commençant à 0.

Les dictionnaires nous laissent une bien plus grande liberté ici puisqu’on va pouvoir
choisir nous mêmes nos clefs (ou index ou indice) et attribuer la clef de notre choix à
chaque valeur à partir du moment où cette clef n’est pas déjà utilisée dans ce
dictionnaire et où la clef est une valeur immuable. La conséquence de cela est que les
valeurs d’un dictionnaire ne sont pas ordonnées à la différence des valeurs d’une
séquence.

Si vous avez des notions en PHP ou dans certains autres langages de script, vous pouvez
retenir que les dictionnaires Python sont l’équivalent des tableaux associatifs dans ces
langages.

Création d’un dictionnaire Python


Pour créer un nouveau dictionnaire, nous allons devoir utiliser un couple
d’accolades { } et définir les paires clef : valeur à l’intérieur des accolades comme ceci :
Comme vous pouvez le voir dans l’exemple ci-dessus, on utilise une nouvelle fois le
syntaxe avec des crochets pour lire les différentes valeurs de notre dictionnaire. Pour
être tout à fait précis, on passe ici une clef entre crochets pour récupérer la valeur qui lui
est associée.

Ajout et modification de valeurs dans un


dictionnaire
Les dictionnaires sont altérables, ce qui signifie qu’on va pouvoir modifier ou ajouter des
valeurs dans un dictionnaire après sa création.

Pour cela, on va tout simplement utiliser le nom de notre dictionnaire suivi d’un couple
de crochets [ ] en passant une clef entre ces crochets puis affecter une valeur à cette clef.
Dans le cas où la clef existe déjà, l’ensemble clef : valeur n’est pas ajouté mais la valeur
originellement liée à la clef est plutôt remplacée par la nouvelle valeur.

Illustrons immédiatement cela avec quelques exemples de manipulation des données de


dictionnaires Python :
Pour supprimer une paire clef : valeur d’un dictionnaire, nous allons utiliser
l’instruction del (abréviation de “delete” = supprimer en anglais) suivi du nom du
dictionnaire avec la clef de l’élément à supprimer entre crochets comme ceci :

Les ensembles ou sets Python


Dans cette leçon, nous allons voir un nouveau type de données Python : les ensembles
ou “set”. Nous allons découvrir l’intérêt de ce type de données et comment créer des
ensembles Python.
 

Présentation des ensembles ou sets Python


Les ensemble ou sets forment un autre type de données composites Python. Un
ensemble est une collection d’éléments non ordonnée, sans index et qui ne peut pas
posséder l’élément dupliqué.
Une des utilisation les plus courantes des ensembles est de les utiliser pour supprimer
des valeurs doublons à partir d’un autre type de données.

Pour créer un ensemble, nous allons utiliser une paire d’accolades { } en placer les
différents éléments de notre ensemble entre ces accolades en les séparant avec une
virgule.

Notez que pour créer un ensemble vide il faudra utiliser la fonction set() car la


syntaxe { } va créer un dictionnaire vide et non pas un ensemble vide.

Récapitulatif sur les types de données et sur


les types composites Python
Dans cette partie, nous avons étudié des types de données simples et des types de
données composites (des données composées de plusieurs éléments) Python.

Les types de données simples étudiés sont les Nombre (entier, décimaux ou complexes),
les Booléens et les Chaines de caractères. Il sont facile à manier et il est simple de savoir
quand utiliser une type plutôt qu’un autre.
Les types de données composite étudiés sont les listes, les tuples, les dictionnaires et les
ensembles. Il est généralement moins évident de choisir quel type de données utiliser ici
car on a tendance à penser “qu’ils se ressemblent tous”.

Voici donc un résumé des grandes caractéristiques de ces types et se qui les différencie :

 Les listes sont des collections d’éléments ordonnés et altérables qui peuvent
contenir plusieurs fois la même valeur ;
 Les tuples sont des collections d’éléments ordonnés et immuables qui peuvent
contenir plusieurs fois la même valeur ;
 Les dictionnaires sont des collection d’éléments non ordonnés mais indexés avec
des clefs de notre choix et altérables qui n’acceptent pas de contenir plusieurs
fois le même élément ;
 Les ensembles sont des collections d’éléments non ordonnées, non indexés et
non modifiables qui n’acceptent pas de contenir plusieurs fois le même élément

Les structures conditionnelles if, if…else


et if…elif…else en Python
Dans cette nouvelle partie, nous allons étudier et comprendre l’intérêt des structures de
contrôle en Python. Une structure de contrôle est un ensemble d’instructions qui permet
de contrôler l’exécution du code.
Il existe différents types de structures de contrôle. Les deux types de structures les plus
communément utilisées sont les structures de contrôle conditionnelles qui permettent
d’exécuter un bloc de code si une certaine condition est vérifiée et les structures de
contrôle de boucle qui permettent d’exécuter un bloc de code en boucle tant qu’une
condition est vérifiée.

Présentation des conditions Python


Les structures de contrôle conditionnelles (ou plus simplement conditions) vont nous
permettre d’exécuter différents blocs de code selon qu’une condition spécifique soit
vérifiée ou pas.
Nous allons très souvent utiliser les conditions avec des variables : selon la valeur
stockée dans une variable, nous allons vouloir exécuter un bloc de code plutôt qu’un
autre.

Python nous fournit les structures conditionnelles suivantes :

La condition if (“si”) ;

 La condition if…else (“si…sinon”) ;
 La condition if…elif…else (“si…sinon si… sinon”) .
Nous allons étudier et comprendre l’intérêt de chacune de ces conditions dans la suite
de cette leçon. Avant de les étudier, cependant, nous allons devoir présenter un nouveau
type d’opérateurs : les opérateurs de comparaison qui vont être au centre de nos
conditions.

Les opérateurs de comparaison


Comme je l’ai précisé plus haut, nous allons souvent construire nos conditions autour de
variables : selon la valeur d’une variable, nous allons exécuter tel bloc de code ou pas.

Pour pouvoir faire cela, nous allons comparer la valeur d’une variable à une certaine
autre valeur donnée et selon le résultat de la comparaison exécuter un bloc de code ou
pas. Pour comparer des valeurs, nous allons devoir utiliser des opérateurs de
comparaison.

Voici ci-dessous les différents opérateurs de comparaison disponibles en Python ainsi


que leur signification :

Opérateur Définition

== Permet de tester l’égalité en valeur et en type

!= Permet de tester la différence en valeur ou en type


Opérateur Définition

< Permet de tester si une valeur est strictement inférieure à une autre

> Permet de tester si une valeur est strictement supérieure à une autre

<= Permet de tester si une valeur est inférieure ou égale à une autre

>= Permet de tester si une valeur est supérieure ou égale à une autre

Notez bien ici que ces opérateurs ne servent pas à indiquer à Python que telle valeur est
supérieure, égale, inférieur ou différente à telle autre valeur. Lorsqu’on utilise un
opérateur de comparaison, on demande au contraire à Python de tester si telle valeur est
supérieure, égale, inférieur ou différente à telle autre valeur. Python va donc comparer
les deux valeurs et toujours renvoyer un booléen : True si la comparaison est vérifiée
ou False dans le cas contraire.

Notez également que les opérateurs de comparaison d’égalité et de différence testent


l’égalité et la différence à la fois sur les valeurs et sur les types. Ainsi, si on demande à
Python de tester l’égalité entre la chaine de caractères “4” et le chiffre 4, celui-ci
renverra False puisque pour lui ces deux valeurs ne sont pas égales.

Regardez plutôt les exemples suivants pour vous en persuader :


Vous pouvez retenir ici que c’est cette valeur booléenne renvoyée par le Python à l’issue
de toute comparaison que nous allons utiliser pour faire fonctionner nos conditions.

La condition if en Python
La structure conditionnelle if est une structure de base qu’on retourne dans de
nombreux langages de script. Cette condition va nous permettre d’exécuter un code si
(et seulement si) une certaine condition est vérifiée.

On va en fait passer une expression à cette condition qui va être évaluée par Python.
Cette expression sera souvent une comparaison explicite (une comparaison utilisant les
opérateurs de comparaison) mais pas nécessairement.

Si Python évalue l’expression passée à True, le code dans la condition if sera exécuté.


Dans le cas contraire, le code dans if sera ignoré.

Prenons immédiatement un premier exemple afin de nous familiariser avec le


fonctionnement et la syntaxe de cette condition :
Nous créons ici deux conditions if. Comme vous pouvez le voir, la syntaxe générale
d’une condition if est if condition : code à exécuter. Pensez bien à indiquer le : et à bien
indenter le code qui doit être exécuté si la condition est vérifiée sinon votre condition ne
fonctionnera pas.

Dans le premier if, nous demandons à Python dévaluer la comparaison x > y. Comme


notre variable x stocke 8 et que notre variable y stocke 4, Python valide cette
comparaison et renvoie True. La condition if reçoit True et le code qu’elle contient est
exécuté.

Dans notre deuxième if, on demande cette fois-ci à Python de nous dire si le contenu
de x est égal au chiffre 5. Ce n’est pas le cas et donc Python renvoie False et le code dans
ce if n’est donc pas exécuté.

Au final, vous pouvez retenir que toute expression qui suit un if va être évaluée par
Python et que Python renverra toujours soit True, soit False. Nous n’avons donc pas
nécessairement besoin d’une comparaison explicite pour faire fonctionner un if.

Pour comprendre cela vous devez savoir qu’en dehors des comparaisons Python
évaluera à True toute valeur passée après if à l’exception des valeurs suivantes qui seront
évaluées à False :

 La valeur 0 (et 0.0) ;
 La valeur None ;
 Les valeurs chaine de caractères vide ””, liste vide [], dictionnaire vide {} et tuile
vide ().

La condition if… else en Python


Avec la condition if, nous restons relativement limités puisque cette condition nous
permet seulement d’exécuter un bloc de code si que le résultat d’un test soit évalué
à True.

La structure conditionnelle if…else (« si… sinon » en français) est plus complète que la


condition if puisqu’elle nous permet d’exécuter un premier bloc de code si un test
renvoie True ou un autre bloc de code dans le cas contraire.

La syntaxe d’une condition if…else va être la suivante :


Ici, on demande dans notre première condition à Python d’évaluer si la valeur de x est
différente du chiffre 5 ou pas. Si c’est le cas, Python renverra True (puisqu’on lui
demande ici de tester la différence et non pas l’égalité) et le code du if sera exécuté.
Dans le cas contraire, c’est le code du else qui sera exécuté.

Notre deuxième condition fait exactement le même travail mais cette fois si on compare
la valeur de yà 5.

Notez bien ici qu’on n’effectuera jamais de test dans un else car le else est par définition
censé prendre en charge tous les cas non pris en charge par le if.

La condition if… elif… else en Python


La condition if…elif…else (« si…sinon si…sinon ») est une structure conditionnelle encore
plus complète que la condition if…else qui vannons permettre cette fois-ci d’effectuer
autant de tests que l’on souhaite et ainsi de prendre en compte le nombre de cas
souhaité.
En effet, nous allons pouvoir ajouter autant de elif que l’on souhaite entre le if de départ
et le else de fin et chaque elif va pouvoir posséder son propre test ce qui va nous
permettre d’apporter des réponses très précises à différentes situations.

Il faut cependant faire attention à un point en particulier lorsqu’on utilise une structure
Python if… elif… else : le cas où plusieurs elif possèdent un test évalué à True par Python.
Dans ce cas là, vous devez savoir que seul le code du premier elif (ou du if si celui-ci est
évalué à True) va être exécuté. En effet, Python sort de la structure conditionnelle dans
son ensemble sans même lire ni tester la fin de celle-ci dès qu’un cas de réussite à été
rencontré et que son code a été exécuté.

Créer des conditions Python complexes


Dans cette nouvelle leçon, nous allons aller plus loin avec les conditions Python est voir
comment créer des conditions complexes en utilisant notamment les opérateurs
logiques et les opérations d’appartenance.
 

Imbriquer des conditions


Souvent, nous allons vouloir comparer plusieurs valeurs au sein d’une même condition,
c’est-à-dire n’exécuter son code que si plusieurs conditions sont vérifiées.
Pour faire cela, nous allons pouvoir soit utiliser plusieurs opérateurs de comparaison, soit
les opérateurs logiques, soit imbriquer plusieurs conditions les unes dans les autres.

Les opérateurs logiques vont nous permettre de créer des conditions plus puissantes
mais dans certains cas il sera plus intéressant et plus rapide d’imbriquer des conditions.

Dans cet exemple, on imbrique deux structures if…else l’une dans l’autre. La première


structure demande à Python de tester si notre variable x contient un nombre strictement
inférieur à 5. Si c’est le cas, on rentre dans le if et on teste donc la condition du
deuxième if. Dans le cas contraire, on va directement au else de fin.

Notre deuxième condition teste si y contient une valeur strictement inférieure à 10. Si
c’est le cas, on exécute le code dans la condition. Sinon, on va directement au else de
cette condition imbriquée.

Utiliser les opérateurs logiques avec les


conditions
Les opérateurs logiques vont être principalement utilisés avec les conditions puisqu’ils
vont nous permettre d’écrire plusieurs comparaisons au sein d’une même condition ou
encore d’inverser la valeur logique d’un test.
Opérateur Définition

and Renvoie True si toutes les deux expressions sont évaluées à True

or Renvoie True si une des comparaisons vaut True

not Renvoie True si la comparaison vaut False (et inversement)

Les opérateurs logiques and et or vont nous permettre de passer plusieurs tests pour


évaluation à Python. On va par exemple pour tester si une variable x contient une valeur
inférieure à 5 et / ou si y contient une valeur inférieure à 10 au sein d’une même
condition.

Dans le cas où on utilise and, chaque expression devra être évaluée à True par Python
pour que le code dans la condition soit exécuté.

Dans le cas où on utilise or, il suffit qu’une expression soit évaluée à True par Python
pour que le code dans la condition soit exécuté.
Ici, vous pouvez noter que Python a l’inverse de la plupart des autres langages possède
une syntaxe très logique et très intuitive qui va nous permettre d’effectuer plusieurs tests
dans une condition “comme si” on utilisait un opérateur logique and en utilisant tout
simplement plusieurs opérateurs de comparaison à la suite.

Je vous recommande cependant plutôt d’utiliser des opérateurs logiques dans cette
situation afin de rendre votre code plus clair.

Finalement, l’opérateur logique not est très particulier puisqu’il nous permet d’inverser la


valeur logique d’un test : si Python renvoie False à l’issue d’une évaluation par exemple et
qu’on utilise l’opérateur not sur cette expression l’opérateur inversera la valeur renvoyée
par Python et la valeur finale passée à la condition sera True.

Présentation des opérateurs d’appartenance


ou d’adhésion
Python met à notre disposition deux opérateurs d’appartenant qui vont nous permettre
de tester si une certaine séquence de caractères ou de valeurs est présente ou pas dans
une valeur d’origine.

Ces opérateurs ne vont fonctionner qu’avec des séquences (chaines de caractères, listes,
etc.) et ne vont donc pas marcher avec des valeurs de type numérique par exemple.

L’opérateur in permet de tester si une certaine séquence de caractères ou de valeurs est


présente dans une valeur d’origine et renvoie True si c’est le cas.
L’opérateur not in permet au contraire de tester si une certaine séquence de caractères
ou de valeurs n’est pas présente dans une valeur d’origine et renvoie True si c’est le cas.

Comme des valeurs booléennes sont renvoyées, on va tout à fait pouvoir utiliser ce type
d’opérateurs au sein de nos conditions même si ils sont communément plus utilisés au
sein de boucles qu’on étudiera dans la prochaine leçon.

Un point sur l’ordre de priorité des


opérateurs
Dans les exemples précédents, nous avons utilisé plusieurs opérateurs différents dans
nos conditions : des opérateurs de comparaisons divers, des opérateurs logiques, etc.

Rien ne nous empêche à priori de rajouter des opérateurs arithmétiques et d’utiliser


plusieurs opérateurs logiques dans ces mêmes conditions.

A partir de là, cependant, il faut commencer à être très rigoureux pour obtenir des
résultats conformes à nos attentes et il va notamment falloir bien connaitre l’ordre de
priorité d’application des différents opérateurs en Python.
Ci-dessous, vous pourrez trouver l’ordre de traitement de chaque opérateur Python
(classés du plus prioritaire au moins prioritaire). Certains nous sont encore inconnus, je
vous demande de ne pas vous en préoccuper pour le moment.

Opérateur Description

() Opérateur de groupement

** Elévation à la puissance

~ Opérateur d’inversion de bit

Opérateurs arithmétiques multiplication, division et


*, /, %
modulo

<<, >> Décalage de bits à gauche ou à droite

& Définit chaque bit à 1 si les deux bits valent 1

Définit chaque bit à 1 si seulement l’un des deux bits


^
vaut 1

Définit chaque bit à 1 si au moins l’un des deux bits


|
vaut 1

==, !=, <, <=, >, >=, in, not in, is, is Opérateurs de comparaison, d’appartenance et


not d’identité

not Opérateur logique (booléen) inverse ou “non”


Opérateur Description

and Opérateur logique (booléen) “et”

or Opérateur logique (booléen) “ou”

Les boucles Python for et while


Les boucles, tout comme les conditions, sont une structure de contrôle Python de base
et il est donc essentiel de comprendre comment elles fonctionnent et de savoir les
utiliser.
 

Présentation des boucles en Python


Les boucles vont nous permettre d’exécuter plusieurs fois un bloc de code, c’est-à-dire
d’exécuter un code « en boucle » tant qu’une condition donnée est vérifiée.

Lorsqu’on code, on va en effet souvent devoir exécuter plusieurs fois un même code.
Utiliser une boucle nous permet de n’écrire le code qu’on doit exécuter plusieurs fois
qu’une seule fois.

Nous allons ainsi pouvoir utiliser les boucles pour parcourir les valeurs d’une variable de
liste liste ou pour afficher une suite de nombres.

Nous avons accès à deux boucles en Python :

La boucle while (“tant que…”) ;


 La boucle for (“pour…”).
Le fonctionnement général des boucles sera toujours le même : on pose une condition
qui sera généralement liée à la valeur d’une variable et on exécute le code de la boucle «
en boucle » tant que la condition est vérifiée.
Pour éviter de rester bloqué à l’infini dans une boucle, vous pouvez donc déjà noter qu’il
faudra que la condition donnée soit fausse à un moment donné (pour pouvoir sortir de
la boucle). Selon le type de condition, on va avoir différents moyens de faire cela. Nous
allons voir les plus courants dans la suite de cette leçon.

La boucle Python while


La boucle while va nous permettre d’exécuter un certain bloc de code « tant qu’une »
condition donnée est vérifiée. Sa syntaxe est la suivante :

On commence ici par créer une variable x et on stocke la valeur 0 dedans.

On crée ensuite notre boucle while qui va baser sa condition de sortie autour de la valeur


de la variable x.
Littéralement, cette boucle signifie “tant que x stocke une valeur strictement inférieure à
10, affiche la valeur de x puis ajoute 1 à cette valeur”.

Lors du premier tour dans la boucle, x stocke la valeur 0 qui est bien inférieure à 10. On
rentre donc dans la boucle, on affiche la valeur de x et on ajoute 1 à cette valeur.

Une fois arrivés en fin de boucle, on retourne au début de la boucle. On teste à nouveau
si x contient une valeur inférieure à 10. C’est le cas puisque x stocke désormais 1. On
affiche à nouveau la valeur de x et on lui ajoute à nouveau 1.

On retourne à nouveau au début de la boucle et etc. Jusqu’à ce que la condition de


sortie soit vérifiée, c’est-à-dire jusqu’à ce que x stocke une valeur supérieure ou égale à
10. Dans ce cas là, la boucle est ignorée et on passe à l’instruction suivante.

Note : Lorsqu’on ajoute 1 à une variable, on dit qu’on l’incrémente. À l’inverse, lorsqu’on
enlève 1 à la valeur d’une variable, on dit qu’on la décrémente. Les opérations
d’incrémentation et de décrémentation sont très fréquentes au sein des boucles. On s’en
sert généralement pour que la condition d’exécution de la boucle soit fausse à un
moment donnée.

La boucle Python for


La boucle Python for possède une logique et une syntaxe différente de celles des
boucle for généralement rencontrées dans d’autres langages.

En effet, la boucle for Python va nous permettre d’itérer sur les éléments d’une séquence
(liste, chaine de caractères, etc.) selon leur ordre dans la séquence.

La condition de sortie dans cette boucle va être implicite : on sortira de la boucle après
avoir parcouru le dernier élément de la séquence.

La syntaxe de cette boucle va être la suivante :


 

La fonction range()
On va pouvoir utiliser la fonction range() pour itérer sur une suite de nombres avec une
boucle for.

Cette fonction permet de générer une suite de valeurs à partir d’une certain nombre et
jusqu’à un autre avec un certain pas ou intervalle.

Dans son utilisation la plus simple, nous allons nous contenter de passer un nombre en
argument (entre les parenthèses) de range(). Dans ce cas, la fonction génèrera une suite
de valeurs de 0 jusqu’à ce nombre – 1 avec un pas de 1. range(5) par exemple génère les
valeurs 0, 1, 2, 3 et 4.

Si on précise deux nombres en arguments de cette fonction, le premier nombre servira


de point de départ pour la génération de nombres tandis que le second servira de point
d’arrivée (en étant exclus). range(5, 10) par exemple permet de générer les nombres 5, 6,
7, 8 et 9.

Finalement, on peut préciser un troisième et dernier nombre en argument de range() qui


nous permet de préciser son pas, c’est-à-dire l’écart entre deux nombres générés.
Ecrire range(0, 10, 2) par exemple permet de générer les nombres 0, 2, 4, 6 et 8.

On va pouvoir utiliser la fonction range() plutôt qu’une variable de type séquence avec


nos boucles for pour itérer sur une suite de nombres.
 

Les instructions break et continue


Les instructions break et continue sont deux instructions qu’on retrouve dans de
nombreux langages et qui sont souvent utilisées avec les boucles mais qui peuvent être
utilisées dans d’autres contextes.

L’instruction break permet de stopper l’exécution d’une boucle lorsqu’une certaine


condition est vérifiée. On l’inclura souvent dans une condition de type if.

Par exemple, on va pouvoir stopper l’exécution d’une boucle lorsqu’une variable contient
une valeur en particulier.

L’instruction continue permet elle d’ignorer l’itération actuelle de la boucle et de passer


directement à l’itération suivante. Cette instruction va donc nous permettre d’ignorer
toute ou partie de notre boucle dans certaines conditions et donc de personnaliser le
comportement de notre boucle.
Introduction aux fonctions Python
Dans cette nouvelle partie, nous allons étudier une autre notion incontournable de tout
langage de programmation qui se respecte : les fonctions. Nous allons notamment
définir ce qu’est une fonction et comprendre l’intérêt d’utiliser ces structures puis nous
verrons comment créer nos propres fonction en Python ainsi que certains concepts
avancés relatifs aux fonctions.
 

Qu’est-ce qu’une fonction ?


Une fonction est un bloc de code nommé. Une fonction correspond à un ensemble
d’instructions créées pour effectuer une tâche précise, regroupées ensemble et qu’on va
pouvoir exécuter autant de fois qu’on le souhaite en “l’appelant” avec son nom. Notez
“qu’appeler” une fonction signifie exécuter les instructions qu’elle contient.

L’intérêt principal des fonctions se situe dans le fait qu’on va pouvoir appeler une
fonction et donc exécuter les instructions qu’elle contient autant de fois qu’on le
souhaite, ce qui constitue au final un gain de temps conséquent pour le développement
d’un programme et ce qui nous permet de créer un code beaucoup plus clair.

Il existe deux grands “types” de fonctions en Python : les fonctions prédéfinies et les
fonctions créées par l’utilisateur.
 

Les fonctions prédéfinies Python


Les fonction prédéfinies sont des fonctions déjà créées et mises à notre disposition par
Python. Dans ce cours, nous avons déjà utilisé des fonctions prédéfinies comme la
fonction print() ou la fonction type() par exemple.

Ici, je tiens à rappeler qu’en programmation rien n’est magique : la “programmation”…


ne représente que des séries d’instruction programmées.

Lorsqu’on a utilisé print() pour afficher des données pour la première fois ou type() pour


connaitre le type d’une donnée, on ne s’est pas posé la question de ce qu’il se passait en
arrière plan.

En fait, ces deux fonctions sont des fonctions complexes et qui contiennent de
nombreuses lignes d’instructions leur permettant d’accomplir une tâche précise :
l’affichage d’un résultat ou la détermination du type d’une valeur en l’occurence.

Cette complexité nous est cachée : nous n’avons qu’à appeler nos fonctions pour
qu’elles fassent leur travail et n’avons pas à écrire la série d’instructions qu’elles
contiennent à chaque fois et c’est tout l’intérêt des fonctions.

Python, dans sa version 3.7.4, met à notre disposition quasiment 70 fonctions prédéfinies
(sans compter les fonctions des modules ou extensions dont nous parlerons plus tard).
Vous pouvez déjà trouver la liste ci-dessous. Nous serons amenés à utiliser la plupart
d’entre elles dans ce cours ; nous les définirons à ce moment là. Considérez le tableau ci-
dessous comme une simple référence.

Liste des fonction prédéfinies Python 3.7.4

abs() delattr() hash() memoryview() set()

all() dict() help() min() setattr()


Liste des fonction prédéfinies Python 3.7.4

any() dir() hex() next() slice()

ascii() divmod() id() object() sorted()

bin() enumerate() input() oct() staticmethod()

bool() eval() int() open() str()

breakpoint() exec() isinstance() ord() sum()

bytearray() filter() issubclass() pow() super()

bytes() float() iter() print() tuple()

callable() format() len() property() type()

chr() frozenset() list() range() vars()

classmethod() getattr() locals() repr() zip()

compile() globals() map() reversed() __import()__

complex() hasattr() max() round()

 
Les fonction Python définies par l’utilisateur
En plus des fonction prédéfinies, Python nous laisse la possibilité de définir nos propres
fonctions. Ces fonctions ne seront bien évidemment disponibles et utilisables que dans
l’espace où elles ont été définies, c’est-à-dire uniquement au sein de nos scripts et non
pas pour l’ensemble des développeurs utilisant Python.

On va vouloir créer nos propres fonctions Python lorsque nos programmes utilisent de
manière répétées une même série d’instructions : plutôt que de réécrire ces instructions
à chaque fois, autant utiliser une fonction !

Les fonctions vont aussi être de très bons outils d’abstraction lorsqu’on voudra distribuer
notre code : on préférera souvent fournir des fonctions à utiliser aux autres
développeurs plutôt que de les laisser se débrouiller avec des séries d’instructions
“sauvages”.

Pour définir une nouvelle fonction en Python, nous allons utiliser le mot clef def qui sert
à introduire une définition de fonction. Ce mot clef doit être suivi du nom de la fonction,
d’une paire de parenthèses au sein desquelles on pourra fournir une liste de paramètres
(nous reviendrons là dessus plus tard) et de : pour terminer la ligne comme ceci def
ma_fonction():.

Le nom d’une fonction Python doit respecter les normes usuelles concernant les noms :
un nom de fonction doit commencer par une lettre ou un underscore et ne contenir que
des caractères alphanumériques classiques (pas d’accent ni de cédille ni aucun caractère
spécial).

Notez que les noms de fonctions sont sensibles à la casse en Python, ce qui signifie que
les fonctions ma_fonction(), Ma_fonction(), ma_FONCtion() et MA_FONCTION() par exemple
seront des fonctions bien différentes pour Python.

Nous allons ensuite placer la liste des différentes instructions de notre fonction à la ligne
suivant sa définition et en les indentant par rapport à la définition afin que Python
comprenne que ces instructions appartiennent à notre fonction. Notez que la première
instruction d’une fonction peut être une chaîne de caractères littérale qui sera alors
utilisée comme chaine de documentation de la fonction.
Créons immédiatement deux fonctions bonjour() et BONJOUR() toutes simples dont le
but va être d’afficher un message en exécutant elles-mêmes une fonction print(). On va
faire cela comme cela :

Nous avons ici défini nos deux premières fonctions. Ces fonctions ne sont pas très utiles
ici : elles se contentent simplement d’exécuter une fonction print() mais c’est déjà un bon
début !

Maintenant que nos fonctions sont créées, nous allons devoir les appeler pour exécuter
le code qu’elles contiennent. Pour cela, nous allons utiliser leur nom suivi d’un couple de
parenthèses. On va pouvoir appeler nos fonctions autant de fois qu’on le souhaite dans
notre script : c’est tout l’intérêt des fonctions !
 

Les paramètres et arguments des fonctions


Les fonctions que nous avons créées ci-dessus se contentent d’exécuter toujours la
même fonction print() et donc de renvoyer toujours le même message.

Elles ne sont pas très utiles en l’état. Un autre aspect fondamental des fonctions est
qu’elles vont pouvoir accepter des informations qui viennent de l’extérieur, c’est-à-dire
qui sont externes à leur définition et qui vont les amener à produire des résultats
différents. Souvent même, les fonctions vont avoir besoin qu’on leur passe des
informations externes pour fonctionner normalement.

C’est par exemple le cas des fonctions print() et type() : ces deux fonctions permettent
d’afficher un message et de déterminer le type d’une donnée. Pour afficher un
message, print() va avoir besoin qu’on lui passe les données qu’elle doit afficher. De
même, type() va avoir besoin qu’on lui fournisse la donnée dont elle doit déterminer le
type.
Ces informations dont vont avoir besoin certaines fonctions pour fonctionner et qu’on va
passer à nos fonctions entre le couple de parenthèses sont appelées des arguments ou
des paramètres.

Pour rester très simple et très schématique ici, on parle de “paramètres” lorsqu’on définit
une fonction, c’est-à-dire lorsqu’on indique dans la définition de la fonction que telle
fonction a besoin d’une, de deux… informations pour fonctionner et on parle
“d’arguments” pour désigner les valeurs effectivement passées à une fonction lorsqu’on
l’utilise.

Illustrons cela immédiatement en reprenant et en modifiant notre fonction bonjour() afin


qu’elle affiche “Bonjour “ suivi du nom de quelqu’un qui va lui être fourni ultérieurement.
Pour réaliser cela, on va indiquer dans la définition de la fonction que celle-ci a besoin
d’un paramètre pour fonctionner.

On peut donner n’importe quel nom à ce paramètre dans la définition puisque celui-ci
sera dans tous les cas remplacé par la valeur effective passée lors de l’appel à la fonction.
Pour une meilleure lisibilité, il est cependant conseillé de fournir des noms descriptifs et
paramètres des fonctions. On peut par exemple l’appeler prenom dans notre cas :

Expliquons ce code. On crée une nouvelle fonction bonjour() dont le rôle est d’afficher


“Bonjour” suivi du prénom de quelqu’un. Pour que cela fonctionne, il va falloir lui passer
un prénom lorsqu’on appelle notre fonction en argument de celle-ci.

Dans la définition de la fonction, on va donc indiquer que notre fonction a besoin d’un
paramètre pour fonctionner. Ici, on choisit le mot “prenom” pour définir notre
paramètre. On aurait aussi bien pu choisir “toto”. Ensuite, dans le corps de notre
fonction, on utilise une fonction print() qui va afficher “Bonjour” suivi du prénom qu’on
aura indiqué lorsqu’on utilisera la fonction.

Ici, je vous rappelle que le mot qu’on utilise comme paramètre lors de la définition de la
fonction sera remplacé par la valeur passée en argument lors de l’appel à la fonction. On
va donc utiliser notre paramètre dans print() afin que cette fonction affiche bien
“Bonjour” suivi d’un prénom.

On utilise ensuite notre fonction plusieurs fois, en lui passant un prénom différent à
chaque fois en argument. La valeur passée va se substituer au paramètre défini lors de la
définition de la fonction.

Le code de notre fonction n’est cependant pas très optimisé ici : en effet, on utilise de la
concaténation dans print() or la concaténation ne va fonctionner que si la valeur passée
est bien une chaine de caractères. Si on passe un un chiffre en argument de bonjour(),
Python renverra une erreur.

Ici, il va être plus efficace de passer le texte et l’argument comme deux arguments
différents de print(). En effet, vous devez savoir que print() est capable d’accepter un
nombre infini d’arguments qu’elle affichera à la suite. Cela résout notre problème de
type de valeurs :
Notions avancées sur les paramètres
des fonctions Python
Dans cette leçon, nous allons étudier quelques concepts relativement avancés liés au
nombre de paramètres des fonctions en passant en revue différentes syntaxes qui vont
nous permettre de passer un nombre variable d’arguments à une fonction.
 

Créer des fonctions acceptant un nombre


variable d’arguments
Dans la leçon précédente, nous avons défini ce qu’étaient des paramètres et des
arguments. Nous avons créé une fonction bonjour() qui avait besoin qu’on lui passe un
argument pour fonctionner comme ceci :

Cette définition impose qu’on passe un et un seul argument à notre fonction pour
qu’elle fonctionne : si on tente de l’appeler sans argument ou en lui passant plusieurs
arguments Python renverra une erreur.

Dans certaines situations, nous voudrons créer des fonctions plus flexibles qui pourront
accepter un nombre variable d’arguments. Cela peut être utile si on souhaite créer une
fonction de calcul de somme par exemple qui devra additionner les différents arguments
passés sans limite sur le nombre d’arguments et sans qu’on sache à priori combien de
valeurs vont être additionnées.

En Python, il existe deux façons différentes de créer des fonctions qui acceptent un
nombre variable d’arguments. On peut :
 Définir des valeurs de paramètres par défaut lors de la définition d’une fonction ;
 Utiliser une syntaxe particulière permettant de passer un nombre arbitraire
d’arguments.

Préciser des valeurs par défaut pour les paramètres


d’une fonction
On va déjà pouvoir préciser des valeurs par défaut pour nos paramètres. Comme leur
nom l’indique, ces valeurs seront utilisées par défaut lors d’un appel à la fonction si
aucune valeur effective (si aucun argument) n’est passée à la place.

Utiliser des valeurs par défaut pour les paramètres de fonctions permet donc aux
utilisateurs d’appeler cette fonction en passant en omettant de passer les arguments
relatifs aux paramètres possédant des valeurs par défaut.

On va pouvoir définir des fonctions avec des paramètres sans valeur et des paramètres
avec des valeurs par défaut. Attention cependant : vous devez bien comprendre qu’ici, si
on omet de passer des valeurs lors de l’appel à la fonction, Python n’a aucun moyen de
savoir quel argument est manquant. Si 1, 2, etc. arguments sont passés, ils
correspondront de facto au premier, aux premier et deuxième, etc. paramètres de la
définition de fonction.

Pour cette raison, on placera toujours les paramètres sans valeur par défaut au début et
ceux avec valeurs par défaut à la fin afin que le arguments passés remplacent en priorité
les paramètres sans valeur.
Si on souhaite s’assurer que les valeurs passées à une fonction vont bien correspondre à
tel ou tel paramètre, on peut passer à nos fonctions des arguments nommés. Un
argument nommé est un argument qui contient le nom d’un paramètre présent dans la
définition de la fonction suivi de la valeur qu’on souhaite passer comme ceci : argument =
valeur.

On va pouvoir passer les arguments nommés dans n’importe quel ordre puisque Python
pourra faire le lien grâce au nom avec les arguments attendus par notre fonction. Notez
cependant qu’il faudra ici passer les arguments nommés en dernier, après les arguments
sans nom. Par ailleurs, aucun argument ne peut recevoir de valeur plus d’une fois. Faites
donc bien attention à ne pas passer une valeur à un argument sans le nommer puis à
repasser cette valeur en le nommant par inattention.
Passer un nombre arbitraire d’arguments avec *args et
**kwargs
La syntaxe *args (remplacez “args” par ce que vous voulez) permet d’indiquer lors de la
définition d’une fonction que notre fonction peut accepter un nombre variable
d’arguments. Ces arguments sont intégrés dans un tuple. On va pouvoir préciser 0, 1 ou
plusieurs paramètres classiques dans la définition de la fonction avant la partie variable.
Ici, on utilise une boucle for pour itérer parmi les arguments : tant que des valeurs sont
trouvées, elles sont ajoutées à la valeur de s. Dès qu’on arrive à court d’arguments,
on print() le résultat.

De façon alternative, la syntaxe **kwargs (remplacez “kwargs” par ce que vous voulez)


permet également d’indiquer que notre fonction peut recevoir un nombre variable
d’arguments mais cette fois-ci les arguments devront être passés sous la forme d’un
dictionnaire Python.

Dans cette exemple, j’utilise la méthode Python items() dont le rôle est de récupérer les
différentes paires clefs : valeurs d’un dictionnaire. Nous reparlerons des méthodes
lorsque nous aborderons l’orienté objet. Pour le moment, vous pouvez considérer
qu’une méthode est l’équivalent d’une fonction.

Séparer des données pour les passer à une


fonction
Les syntaxes *args et **kwargs peuvent être utilisées pour réaliser les opérations inverse
de celles présentés ci-dessus, à savoir séparer des données composites pour passer les
valeurs ou éléments de ces données un à un en arguments des fonctions.

On, utilisera la syntaxe *args pour séparer les arguments présents dans une liste ou un
tuple et la syntaxe **kwargs pour séparer les arguments présents dans un dictionnaire et
fournir des arguments nommés à une fonction.

Contrôle des valeurs de retour d’une


fonction Python
Dans cette leçon, nous allons voir comment faire pour que nos fonctions retournent
explicitement une valeur et comprendre l’intérêt de faire retourner une valeur à nos
fonctions Python.
 
Présentation de l’instruction return et cas
d’utilisation
Jusqu’à présent, nos fonctions n’ont fait qu’afficher leur résultat après qu’on les ait
appelées. En pratique, cette façon de procéder est rarement utilisée et ceci pour deux
raisons : d’une part, nous n’avons aucun contrôle sur le résultat affiché puisque celui est
affiché dès que la fonction a fini de s’exécuter et ensuite car nous ne pouvons pas utiliser
ce résultat pour effectuer de nouvelles opérations.

Or, en programmation, nous voudrons souvent récupérer le résultat d’une fonction afin
de l’utiliser dans le reste de notre script. Pour cela, il va falloir qu’on demande à notre
fonction de retourner (renvoyer) le résultat de ses opérations. Nous allons pouvoir faire
cela en Python grâce à l’instruction return.

Attention cependant : l’instruction return va terminer l’exécution d’une fonction, ce qui


signifie qu’on placera généralement cette instruction en fin de fonction puisque le code
suivant une instruction return dans une fonction ne sera jamais lu ni exécuté.

Premier exemple d’utilisation de return en


Python
Imaginons que nous soyons en train de créer un programme relativement complexe qui
effectue des séries de calculs intermédiaires pour finalement arriver à un résultat final.

Notre programme va être composé de différentes fonctions qui vont se charger


d’effectuer ces différents calculs à la suite les unes des autres. Certaines fonctions vont
fonctionner différemment ou même ne pas s’exécuter du tout en fonction du résultat
renvoyé par la fonction précédente dans la chaine de fonctions.

Ce type de situations est très fréquent en programmation : on exécute une première


fonction qui renvoie un résultat et on injecte ce résultat dans la fonction suivante et etc.
On va pouvoir faire cela avec une instruction return.
Pour cela, créons par exemple une fonction très simple qui renvoie la différence entre
deux nombres.

Ici, on utilise return afin de demander à notre fonction de retourner son résultat. On


stocke ensuite ce résultat dans une variable x dont on pourra se resservir dans la suite
du script.

Utiliser return pour retourner plusieurs


valeurs
Une fonction ne peut retourner qu’une donnée à la fois. Cependant, Python met à notre
disposition des types de données composites comme les listes ou les tuples par
exemple.

On va donc pouvoir utiliser return pour faire retourner “plusieurs valeurs” à la fois à nos


fonctions ou pour être tout à fait exact pour leur faire retourner une donnée composite.

Pour cela, on va préciser les différentes valeurs que doit retourner return en les séparant
par des virgules. Les valeurs retournées seront retournées dans un tuple.
 

Les fonctions récursives


Nous avons vu dans les leçon précédente qu’une fonction pouvait exécuter une autre
fonction, par exemple dans le cas où on demande à une fonction d’exécuter une
fonction print() pour afficher une valeur.

Vous devez savoir qu’une fonction peut également s’appeler elle même dans son
exécution : c’est ce qu’on appelle la récursivité. Lorsqu’on définit une fonction récursive,
il faudra toujours faire bien attention à fournir une condition qui sera fausse à un
moment ou l’autre au risque que la fonction s’appelle à l’infini.

L’exemple de fonction récursive par excellence est la définition d’une fonction qui
calculerait une factorielle. La factorielle d’un nombre est le produit des nombres entiers
inférieurs ou égaux à celui-ci; la factorielle de 4 par exemple est égale à 4 * 3 * 2 * 1.

Créons immédiatement cette fonction :


Ici, la condition de sortie de notre fonction est atteinte dès que la valeur passée en
argument atteint ou est inférieure à 1. Expliquons comment fonctionne cette fonction en
détail. Si on passe une valeur inférieure ou égale à 1 à notre fonction au départ, on
retourne la valeur 1 et la fonction s’arrête.

Si on passe une valeur strictement supérieure à 1, on retourne cette valeur et on


appelle factorielle(n-1). Si n-1 représente toujours une valeur strictement supérieure à 1,
on retourne cette valeur et on appelle à nouveau notre fonction avec une valeur
diminuée de 1 et etc. Jusqu’à ce que la valeur passée à factorielle() atteigne 1.

Un peu de vocabulaire : fonction vs


procédure en Python
Par définition, toute fonction est censée renvoyer une valeur. Une fonction qui ne
renvoie pas de valeur n’est pas une fonction : on appelle cela en programmation une
procédure.

En Python, en fait, même les fonctions sans instruction return explicite renvoient une


valeur qui est None. Le valeur None est une valeur qui correspond justement à l’absence
de valeur. Cette valeur sert à indiquer “il n’y a pas de valeur”.
L’interpréteur Python l’ignore lorsque c’est la seule valeur qui est renvoyée mais elle
existe tout de même et c’est la raison pour laquelle on appelle les fonctions qui ne
possèdent pas de return explicite des fonctions en Python.

La portée des variables en Python


Dans cette leçon, nous allons découvrir un concept fondamental lié aux fonctions et aux
variables qui est celui de portée des variables. Nous allons comprendre les conditions
d’accès et d’utilisation des différentes variables dans un script.
 

Définition de la portée des variables en


Python
En Python, nous pouvons déclarer des variables n’importe où dans notre script : au
début du script, à l’intérieur de boucles, au sein de nos fonctions, etc.

L’endroit où on définit une variable dans le script va déterminer l’endroit où la variable


va être accessible c’est-à-dire utilisable.

Le terme de “portée des variables” sert à désigner les différents espaces dans le script
dans lesquels une variable est accessible c’est-à-dire utilisable. En Python, une variable
peut avoir une portée locale ou une portée globale.

 
Variables globales et variables locales en
Python
Les variables définies dans une fonction sont appelées variables locales. Elles ne peuvent
être utilisées que localement c’est-à-dire qu’à l’intérieur de la fonction qui les a définies.
Tenter d’appeler une variable locale depuis l’extérieur de la fonction qui l’a définie
provoquera une erreur.

Cela est dû au fait que chaque fois qu’une fonction est appelée, Python réserve pour elle
(dans la mémoire de l’ordinateur) un nouvel espace de noms (c’est-à-dire une sorte de
dossier virtuel). Les contenus des variables locales sont stockés dans cet espace de noms
qui est inaccessible depuis l’extérieur de la fonction.

Cet espace de noms est automatiquement détruit dès que la fonction a terminé son
travail, ce qui fait que les valeurs des variables sont réinitialisées à chaque nouvel appel
de fonction.

Les variables définies dans l’espace global du script, c’est-à-dire en dehors de toute
fonction sont appelées des variables globales. Ces variables sont accessibles (=
utilisables) à travers l’ensemble du script et accessible en lecture seulement à l’intérieur
des fonctions utilisées dans ce script.
Pour le dire très simplement : une fonction va pouvoir utiliser la valeur d’une variable
définie globalement mais ne va pas pouvoir modifier sa valeur c’est-à-dire la redéfinir. En
effet, toute variable définie dans une fonction est par définition locale ce qui fait que si
on essaie de redéfinir une variable globale à l’intérieur d’une fonction on ne fera que
créer une autre variable de même nom que la variable globale qu’on souhaite redéfinir
mais qui sera locale et bien distincte de cette dernière.

Modifier une variable globale depuis une


fonction
Dans certaines situations, il serait utile de pouvoir modifier la valeur d’une variable
globale depuis une fonction, notamment dans le cas où une fonction se sert d’une
variable globale et la manipule.

Cela est possible en Python. Pour faire cela, il suffit d’utiliser le mot clef global devant le
nom d’une variable globale utilisée localement afin d’indiquer à Python qu’on souhaite
bien modifier le contenu de la variable globale et non pas créer une variable locale de
même nom.

Annexe 1 : Quelques fonctions Python


utiles
Nous connaissons déjà bien les fonction print() et type() qui permettent respectivement
d’afficher des données ou de connaitre le type d’une donnée Python.
Python ne contient pas énormément de fonctions prédéfinies -seulement celles qui
s’avèrent le plus utiles- et la plupart d’entre elles sont donc très régulièrement utilisées.

Vous trouverez dans la suite de cette leçon quelques définitions de fonctions qui
pourront vous servir par la suite.

Les fonctions de conversion


Python possède certaines fonctions qui nous permettent de modifier le type de certaines
données, c’est-à-dire de les “convertir”. Ces fonctions portent le nom du type de donnée
souhaitée :

 La fonction str() retourne une chaine de caractères à partir d’une donnée qu’on va


lui passer en argument ;
 La fonction int() retourne un entier à partir d’un nombre ou d’une chaine
contenant un nombre qu’on va lui passer en argument ;
 La fonction float() retourne un nombre décimal à partir d’un nombre ou d’une
chaine contenant un nombre qu’on va lui passer en argument ;
 La fonction complex() retourne un nombre complexe à partir d’un nombre ou
d’une chaine contenant un nombre qu’on va lui passer en argument ;
 La fonction bool() retourne un booléen à partir d’une donnée qu’on va lui passer
en argument ;
 La fonction list() retourne une liste à partir d’une donnée itérable (une donnée
dont on peut parcourir les valeurs) ;
 La fonction tuple() retourne un tuple à partir d’une donnée itérable ;
 La fonction dict() crée un dictionnaire à partir d’un ensemble de paires clef =
“valeur” ;
 La fonction set() retourne un ensemble (set) à partir d’une donnée itérable.
 

Les fonctions mathématiques


Python possède également certaines fonctions qui vont nous permettre d’effectuer des
opérations mathématiques intéressantes, comme des calculs de somme ou de
recherches du plus grand ou du plus petit nombre dans une liste.

Nous allons ici étudier les fonctions range(), round(), sum(), min() et max().

La fonction range() renvoie une séquence de nombres. On peut lui passer jusqu’à 3


arguments mais 1 seul est obligatoire.

Si on ne passe qu’un argument à range(), cette fonction va renvoyer une séquence de


nombres commençant par 0 et en incrémentant de 1 à chaque fois jusqu’au nombre
spécifié en argument moins 1.

En lui passant 2 arguments, le premier argument servira de départ pour la séquence et le


deuxième indiquera la fin de la séquence (avec le nombre indiqué exclu).

En lui passant trois arguments, le premier argument servira de départ pour la séquence,
le deuxième indiquera la fin de la séquence (avec le nombre indiqué exclu) et le
troisième indiquera le “pas”, c’est-à-dire l’écart entre chaque nombre renvoyé.

La fonction round() permet d’arrondir un nombre spécifié en argument t à l’entier le plus


proche avec un degré de précision (un nombre de décimales) éventuellement spécifié en
deuxième argument.

Le nombre de décimales par défaut est 0, ce qui signifie que la fonction retournera
l’entier le plus proche.

La fonction sum() permet de calculer une somme. On peut lui passer une liste de


nombres en arguments par exemple. On peut également lui passer une valeur “de
départ” en deuxième argument qui sera ajoutée à la somme calculée.

La fonction max() retourne la plus grande valeur d’une donnée itérable, c’est-à-dire


d’une donnée dont on peut parcourir les différentes valeurs.

On peut lui passer autant d’arguments qu’on souhaite comparer de valeurs. Notez qu’on
peut également comparer des chaines même si max() est peu souvent utilisée pour faire
cela.
La fonction min(), au contraire, retourne la plus petite valeur d’une donnée itérable. Elle
s’utilise exactement comme max().
 

Autres fonctions Python natives utiles


Parmi les autres fonctions Python prédéfinies, j’aimerais vous en présenter rapidement
quelques unes qu’on va réutiliser dans la suite de ce cours.

La fonction len(), tout d’abord, renvoie la longueur ou le nombre de valeurs d’une


donnée de type séquence ou collection.

La fonction input() permet de dialoguer et d’échanger des données avec l’utilisateur. On


va pouvoir passer un message en argument de cette fonction. Attention : il est de votre
responsabilité de bien vérifier si les données envoyées sont conformes à celles attendues
pas la suite.

La fonction dir(), lorsqu’elle est utilisée sans argument, renvoie la liste des variables et
des fonctions (ou plus exactement des objets et des méthodes) disponibles dans
l’espace de portée courant. Nous étudierons ce que sont les objets et méthodes par la
suite.

Si on lui passe une donnée en argument, elle renverra la liste des méthodes disponibles
pour ce type de donnée.
Introduction à l’orienté objet en Python
La programmation orientée objet (POO) est un passage obligé lors de l’apprentissage de
nombreux langage informatiques et est également un sujet relativement ardu lorsqu’on
nous le présente pour la première fois.
Cette première leçon a pour objectif de définir le plus simplement et le plus clairement
les concepts d’objets, de classes et d’attributs et de démystifier le sujet de l’orienté objet.

Il est possible que vous ne compreniez pas tout d’un coup : pas d’inquiétude, suivez le
cours à votre rythme, avec moi, et les choses deviendront de plus en plus claires au fil de
votre avancement de le cours. N’hésitez pas à relire cette partie en entier une fois que
vous l’avez terminée pour revoir tous ces concepts sous un oeil nouveau.

Qu’est-ce que la programmation orientée


objet ?
La programmation orientée objet (ou POO en abrégé) correspond à une autre manière
d’imaginer, de construire et d’organiser son code.

La programmation orientée objet repose sur le concept d’objets qui sont des entités qui
vont pouvoir posséder un ensemble de variables et de fonctions qui leur sont propres.

Les objectifs principaux de la programmation orientée objet sont de nous permettre de


créer des scripts plus clairs, mieux structurés, plus modulables et plus faciles à maintenir
et à déboguer. Nous allons illustrer cela en pratique au cours de cette partie.

Le Python, un langage orienté objet


Python est un langage résolument orienté objet, ce qui signifie que le langage tout
entier est construit autour de la notion d’objets.

En fait, quasiment tout en Python est avant tout un objet et nous avons manipulé des
objets depuis le début de ce cours sans nous en rendre compte : les types str, int, list, etc.
sont avant tout des objets, les fonctions sont des objets, etc.

Pour véritablement maitriser Python et utiliser toutes ses fonctionnalités, il est donc
indispensable de comprendre cette composante orienté objet.

Qu’est-ce qu’un objet en programmation ?


Dans la vie réelle, un objet possède des caractéristiques et nous permet de réaliser des
actions. Un crayon par exemple possède une taille, une couleur, une forme, etc. qui sont
ses caractéristiques et permet d’écrire ou de dessiner.

Le concept d’objets en informatique s’inspire fortement de cette définition de la vie


réelle : on va appeler “objet” un bloc cohérent de code qui possède ses propres variables
(qui sont l’équivalent des caractéristiques des objets de tous les jours) et fonctions (qui
sont nos actions). Comme les objets de la vie courante, les objets informatiques peuvent
être très simples ou très complexes.

Vous pouvez déjà noter que Python parle “d’attributs” pour désigner les variables et
fonctions d’un objet et plus précisément “d’attributs de données” pour désigner les
variables d’un objet et de “méthodes” pour désigner les fonctions qui lui sont propres.

Dans la plupart des langages informatiques, on parle plutôt de “membres” pour désigner
les variables et fonctions d’un objet et de “propriété” pour désigner les variables et de
“méthodes” pour désigner les fonctions.

Comment crée-t-on un objet ? Présentation


des classes
En POO, un objet ne peut pas être créé ex nihiliste (à partir de rien). La plupart des
langages qui supportent l’orienté objet (dont le Python) utilisent d’autres entités pour
créer des objets qu’on appelle des classes.

Une classe est également un ensemble cohérent de code qui contient généralement à la
fois des variables et des fonctions et qui va nous servir de plan pour créer des objets
possédant un même ensemble de d’attributs de données et de méthodes de base.

En fait, on peut aller jusqu’à considérer que les classes sont les principaux outils de la
POO puisqu’elles permettent de mettre en place des concepts fondamentaux de la POO
comme l’héritage, l’encapsulation ou le polymorphisme qui sont des concepts qu’on
expliquera et qu’on étudiera en détail plus tard.
Pour le moment, contentez vous de retenir qu’une classe va servir de plan de création
pour un type d’objets. Créer une nouvelle classe en Python correspond à définir un
nouveau type d’objets ou un nouveau type de données.

Pour créer des objets à partir d’une classe en Python, on va utiliser cette classe comme
une fonction. Pour illustrer concrètement comment cela fonctionne et pour que vous
compreniez plus facilement, créons immédiatement une première classe qu’on va
appeler Utilisateur.

Création d’une première classe et d’objets


Python
Pour créer une nouvelle classe Python on utilise le mot clef class suivi du nom de notre
classe. Ici, on va créer une classe Utilisateur qui va être très simple pour le moment.

Je vous accorde que ce code peut faire peut à priori car il contient de nombreuses
nouvelles choses. Pas d’inquiétude, nous allons l’expliquer au fur et à mesure.

Ici, on crée une nouvelle classe Utilisateur avec la syntaxe class Utilisateur:. Notez que par
convention le nom d’une classe commence toujours par une majuscule.

Cette classe Utilisateur possède ici deux variables statut et age et définit également une


fonction setNom(). Le rôle de la fonction setNom() va être de permettre par la suite à nos
objets de type Utilisateur() de définir un attribut de donnée nom avec une valeur qui va
être propre à chacun. Je vous demande de ne pas vous préoccuper de l’argument self le
moment.
Pour créer des objets à partir de cette classe, nous allons utiliser la
syntaxe Utilisateur() comme ceci :

Lorsqu’on crée un objet à partir d’une classe comme ceci, on dit également qu’on
instancie une classe (on crée une nouvelle instance d’une classe). Ici, on instancie deux
fois notre classe et on place le résultat dans deux variables pierre et mathilde qui
deviennent automatiquement des objets de type Utilisateur.

La chose que vous devez absolument comprendre ici est que les objets créés à partir
d’une classe en Python vont automatiquement avoir accès aux variables et fonctions
définies dans la classe qui vont être pour eux des attributs de données et des méthodes.

Nos objets pierre et mathilde disposent donc ici tous les deux de deux attributs de


données statut et age qui possèdent les valeurs Inscrit et 0 et ont également accès à la
méthode setNom().

Pour accéder aux attributs de données et aux méthodes d’un objet, il va falloir
mentionner l’objet suivi de l’opérateur . (point) suivi du nom de l’attribut de donnée ou
de la méthode à laquelle on souhaite accéder comme ceci :
Ce n’est pas tout : nos objets vont également pouvoir définir des valeurs personnalisées
pour leurs attributs de données et on va également pouvoir définir de nouveaux
attributs de données qui vont être propres à un objet en particulier dans une classe :

 
Conclusion sur cette introduction à l’orienté
objet Python
Nous venons de faire une première (grosse) introduction à la programmation orientée
objet et avons dans cette leçon défini et découvert de nombreuses nouvelles entités
comme les objets, les classes, etc. et de nouveaux concepts comme l’encapsulation,
l’héritage, etc.

Si vous ne comprenez pas tout pour le moment et si vous êtes un peu perdu, aucune
inquiétude : c’est tout à fait normal. Considérez qu’entamer la POO est un petit peu
comme si vous commenciez ce cours.

Plus vous allez avancer dans cette partie, plus les différents éléments vont faire sens et
mieux vous comprendrez chaque chose car la plupart des concepts présentés ici ont
besoin que vous connaissiez d’autres concepts pour être compris mais pour vous
présenter ces autres concepts j’ai besoin de vous présenter avant les premier concepts
bref… C’est l’histoire du serpent qui se mord la queue ou de l’oeuf et la poule : il faut
choisir un angle d’attaque pour expliquer la suite et progresser.

Pour le moment, je vous conseille de ne pas trop vous formaliser sur cette nouvelle
syntaxe ni sur les nouveaux termes. Essayez simplement de retenir ces deux points pour
la suite :

 Les classes sont des ensembles de code qui contiennent des variables et des
fonctions et qui vont nous servir à créer des objets ;
 Les objets créés à partir d’une classe disposent automatiquement des variables et
des fonctions définies dans la classe.

Classes, objets et attributs en Python


orienté objet
L’objectif de cette leçon est de clarifier certains des concepts vus dans la leçon
précédente et de comprendre comment utiliser nos classes et nos objets en détail.
 
Différence entre variable et attribut de
données et entre fonction et méthode
Les classes permettent de réunir des données et des fonctionnalités. Ici, vous devez bien
comprendre qu’une classe n’est finalement qu’un objet qui permet de créer d’autres
objets de même type. Comme cet objet est différent des autres, on appelle cela une
“classe” mais ce n’est que du vocabulaire.

Créer une nouvelle classe en Python revient à créer un nouveau type d’objet et de fait un
nouveau type de données. On va ensuite pouvoir instance notre classe pour créer des
objets qui vont partager les variables et fonctions de leur classe.

Pour désigner les variables et les fonctions que les objets héritent de leur classe, Python
utilise les termes “attributs de données” et “méthodes”.

Les termes employés sont différents (et le sont dans tous les langages qui supportent
l’orienté objet) car ils servent à désigner des éléments de langage différents.

L’idée principale à retenir ici est qu’un attribut de donnée ou une méthode est propre à
un objet tandis qu’une variable ou une fonction est indépendante de tout objet. C’est la
raison pour laquelle pour accéder à un attribut de données ou à une méthode on doit
préciser le nom de l’objet qui souhaite y accéder avant.

Si on tente d’accéder à un attribut de donnée ou à une méthode définis dans une classe
sans objet ou à partir d’un objet d’une autre classe, Python renverra une erreur
puisqu’encore une fois les attributs de données de classe et les méthodes de classes
sont propres et ne sont partagés que par les objets de la classe. C’est le principe
“d’encapsulation” que nous allons expliquer en détail juste après.

En plus de cela, notez qu’un objet peut également définir ses propres attributs de
données ou surcharger des attributs de données de classe.

Les classes et le principe d’encapsulation


L’un des grands intérêts des classes est qu’elles permettent l’encapsulation du code,
c’est-à-dire le fait d’enfermer le code dans une “capsule”, dans un espace en dehors de
l’espace global. Cela permet d’éviter d’utiliser des variables globales et de polluer
l’espace global du script.

En effet, dans tous les langages de programmation, il est considéré comme une bonne
pratique de limiter le recours aux variables globales car cela rend le code non flexible,
non modulable, et dur à entretenir.

Pour comprendre cela, il faut penser au fait que la plupart des programmes aujourd’hui
contiennent des dizaines de fichiers qui contiennent chacun des centaines de lignes de
code et qui font appel à de nombreux modules externes, c’est-à-dire à des code
préconçus fournis par d’autres personnes.

Dans ces conditions, on ne peut pas se permettre de déclarer ses variables ou fonction
n’importe comment car les risques de conflits, c’est-à-dire les risques qu’un même nom
de variable ou de fonction soit utilisé plusieurs fois pour définir plusieurs variables ou
fonctions entre fichiers et modules sont grands.

Pour cette raison, un bon développeur fera tout pour compartimenter son code en
créant des espaces de portée ou “espaces de noms” bien définis et dont les éléments ne
pourront pas entrer en conflit avec les autres.

Les classes nous permettent de mettre en place cela puisque chaque objet créé à partir
d’une classe sa posséder SES attributs de données et SES méthodes qui ne vont pas être
accessibles depuis l’extérieur de l’objet et qui ne vont donc pas polluer l’espace global.

Initialiser des objets avec __init__()


Dans la leçon précédente, nous avons défini une première classe Utilisateur() et avons
créé deux objets pierre et mathilde à partir de cette classe comme cela :
Ici, lors de leur création, les deux objets pierre et mathilde disposent des mêmes attributs
avec les mêmes valeurs telles que définies dans la classe.

Ce type de comportement est, en pratique, rarement voulu. Généralement, on voudra


que les objets disposent déjà d’attributs avec des valeurs qui leur sont propres dès leur
création.

Pour réaliser cela, nous allons modifier notre classe et lui ajouter une fonction spéciale
appelée __init__() (deux underscores avant et deux après le nom) qui permet
“d’initialiser” ou de “construire” nos objets.

En fait, cette fonction __init__() va être automatiquement exécutée dès qu’on va


instancier la classe. Cette fonction va pouvoir recevoir des arguments qu’on va lui
transmettre durant l’instanciation et qui vont nous permettre de définir des valeurs
propres à chaque instance.

L’idée générale est la suivante : notre fonction __init__() va être construite de telle sorte à
ce que les arguments passés soient utilisés comme valeur d’initalisation pour les
attributs d’une instance. On va passer les argument lors de l’instanciation,
via Utilisateur() dans notre cas et ces arguments vont être transmis à __init__().

Prenons immédiatement un exemple qu’on va expliquer ensuite pour bien comprendre


comment cela se passe :
Notre classe Utilisateur() est désormais composée d’une variable anciennete et de deux
fonctions __init()__ et getNom().

Observons de plus près notre fonction __init__(). Comme vous pouvez le voir, celle-ci
accepte trois paramètres en entrée qu’on a ici nommé self, nom et age.

Il est maintenant temps de vous expliquer ce que signifie ce self qui était déjà présent
dans notre dernière définition de classe. Pour cela, il faut retourner à notre définition des
méthodes.

Si vous vous rappelez bien, je vous ai dit au début de cette partie que quasiment tout en
Python était avant tout un objet et qu’en particulier les fonctions étaient des objets de
“type” fonction. Les fonctions d’une classe ne font pas exception : ce sont également
avant tout des objets.

Ces objets fonctions de classes définissent les méthodes correspondantes de ses


instances. Schématiquement, les fonctions des classes deviennent des méthodes pour les
objets créés à partir de cette classe.

Ce que vous devez absolument comprendre ici est qu’une des particularités des
méthodes est que l’objet qui l’appelle est passé comme premier argument de la fonction
telle que définie dans la classe. Ainsi, lorsqu’on écrit pierre.getNom() par exemple,
l’objet pierre est passé de manière implicite à getNom().

C’est la raison pour laquelle nos fonctions de classe possèdent toujours un paramètre de
plus que d’arguments qui leur sont fournies lorsqu’elles sont appelées en tant que
méthode : l’objet qui les appelle prendra la place de ce paramètre. Par convention, on
appelle ce paramètre self qui signifie “soi-même” pour bien comprendre que c’est l’objet
lui même qui va être passé en argument.

Notez ici qu’en Python “self” ne signifie rien et qu’on pourrait tout aussi bien utiliser un
autre nom, à la différence de nombreux autres langages orienté objet où self est un mot
clef réservé.

Revenons en maintenant à notre fonction __init__(). Lorsqu’on instancie notre classe,


c’est-à-dire lorsqu’on crée un nouvel objet à partir de cette classe, la
fonction __init__() est automatiquement appelée si elle est présente dans la définition de
la classe.

Cette fonction va également recevoir l’objet qui est en train d’être créé en premier
argument. Cet objet va donc remplacer le “self”. Ici, notre fonction __init__() sert à
effectuer deux affectations : self.user_name = nom et self.user_age = age.

Ces deux affectations signifient littéralement “crée un attribut de données user_name qui


sera propre à l’instance et affecte lui la valeur passée en argument nom” et “crée un
attribut de données user_age qui sera propre à l’instance et affecte lui la valeur passée en
argument age”.

Lorsqu’on écrit pierre = Utilisateur("Pierre", 29), les deux arguments passés “Pierre” et “29”
vont être transmis avec l’objet à __init__() qui va les utiliser pour créer deux attributs de
données user_name et user_age spécifique à l’objet pierre créé.
 

Variables de classe et attributs de données


d’un objet
De manière générale, il est considéré comme une bonne pratique de ne créer des
variables de classe que pour définir des variables qui devraient avoir des valeurs
constantes à travers les différents objet de la classe lors de leur création.

Dans l’exemple précédent, par exemple, on peut imaginer que notre


classe Utilisateur nous sert à créer un nouvel objet de type “Utilisateur” dès qu’une
personne s’enregistre sur notre site.

Dans ce cas, l’ancienneté de l’utilisateur au moment de la création de l’objet, c’est-à-dire


au moment de son inscription sera toujours égale à 0 et il fait sens de définir une
variable de classe anciennete.

Retenez également qu’on évitera de créer des variables de classe avec des données
altérables comme des listes ou des dictionnaires sauf dans des cas très précis. En effet,
une variable de classe “appartient” à tous les objets de la classe par défaut.

Si la variable contient des données altérables, alors n’importe quel objet va pouvoir
modifier ces données. Or, si un objet modifie les données d’une telle variable de classe,
le contenu de la variable sera modifié pour tous les objets de la classe.

Cela est dû au fait qu’une variable de classe est en fait “partagée” par tous les objets de
la classe. On dit que chaque objet de la classe accède à la variable par référence.
Héritage et polymorphisme en Python
orienté objet
L’héritage et le polymorphisme forment avec le principe d’encapsulation les trois piliers
de la programmation orientée objet. Dans cette leçon, nous allons présenter et étudier
ces concepts en détail et comprendre pourquoi et comment les implémenter dans notre
code.
 

Présentation du concept d’héritage en


Python orienté objet
En programmation orientée objet, “hériter” signifie “avoir également accès à”. Lorsqu’on
dit qu’un objet “hérite” des méthodes de la classe qui l’a défini, cela signifie que l’objet
peut utiliser ces méthodes; qu’il y a accès.

La notion d’héritage va être particulièrement intéressante lorsqu’on va l’implémenter


entre deux classes. En Python, nous allons en effet pouvoir créer des “sous-classes” ou
des classes “enfants” à partir de classes de base ou classes “parentes”.
La syntaxe pour définir une sous-classe à partir d’une classe de base est la suivante :

Ici, Utilisateur est notre classe de base et Client est notre sous-classe.

Par défaut, la sous-classe hérite de toutes les variables et fonctions de la classe parent
(et notamment de sa fonction __init__()) et peut également définir ses propres variables
et fonctions. On va ensuite pouvoir instancier la classe enfant pour créer de nouveaux
objets et ces objets vont avoir accès aux variables et fonctions définies à la fois dans la
sous-classe et dans la classe de base.
Ce principe d’héritage va nous permettre de créer des classes de base qui vont définir
des fonctionnalités communes à plusieurs classes puis des sous-classes qui vont hériter
de ces fonctionnalités et pouvoir également définir leurs propres fonctionnalités.

Cela permet in-fine d’obtenir un code plus modulable, mieux organisé, plus clair et plus
concis qui sont des objectifs majeurs pour tout bon développeur.

La surcharge des méthodes de classe


“Surcharger” une méthode signifie la redéfinir d’une façon différente. En Python, les
classes filles ou sous-classes vont pouvoir surcharger les méthodes héritées de leur
classe parent et également pouvoir définir des variables de même nom que celles de
leur classe parent.

On ne parlera de surcharge que pour les méthodes car dans le cas des variables définir
une variable avec le même nom dans la sous-classe correspond finalement à créer une
variable locale à la sous-classe en plus de celle “globale” (celle disponible dans la classe
de base) mais ces deux variables continuent d’exister à part entière et à être différente
tandis que lorsqu’on réécrit une méthode la nouvelle méthode remplace véritablement
l’ancienne pour les objets de la sous-classe.

Réécrivons notre classe Client() afin de définir certaines variables locales et de surcharger


les méthodes de la classe mère Utilisateur :
Notez qu’en pratique, on ne voudra souvent pas simplement réécrire l’intégralité du
code d’une classe mère dans une classe fille (cela signifierait que nos classes sont mal
construites) mais on voudra simplement “étendre” la méthode c’est à dire lui rajouter
des instructions spécifiques pour une classe fille.

On va pouvoir faire cela en appelant la méthode de notre classe mère depuis notre
classe fille avec la syntaxe ClasseDeBase.nomDeMethode(), ce qui va nous permettre de
récupérer l’intégralité du code de la classe mère.

Modifions à nouveau notre classe Client afin d’étendre la fonction __init__() de la classe


mère :
 

Les tests d’héritage Python


A ce niveau du cours, vous pourriez (et devriez) vous poser la question suivante :
comment l’objet fait pour déterminer si il doit utiliser les variables ou méthodes de sa
classe ou de la classe mère dont sa classe hérite ?

La réponse à cette question est très simple : Python va rechercher les variables et
méthodes dans un ordre précis.

Lorsqu’on tente d’afficher le contenu d’un attribut de données ou d’appeler une


méthode depuis un objet, Python va commencer par chercher si la variable ou la
fonction correspondantes se trouvent dans la classe qui a créé l’objet. Si c’est le cas, il va
les utiliser. Si ce n’est pas le cas, il va chercher dans la classe mère de la classe de l’objet
si cette classe possède une classe mère. Si il trouve ce qu’il cherche, il utilisera cette
variable ou fonction. Si il ne trouve pas, il cherchera dans la classe mère de la classe
mère si elle existe et etc.

Python va en fait “remonter” le long de la chaine d’héritage des classes jusqu’à trouver
l’information demandée. Si. Elle n’est jamais trouvée, il renverra finalement une erreur.

Notez ici que Python nous fournit également deux fonctions pour nous permettre de
tester le type d’une instance et l’héritage d’une classe.

La fonction isinstance() permet de tester le type d’une instance, c’est-à-dire le type d’une


objet, c’est-à-dire permet de savoir si un objet appartient à une certaine classe ou pas.
On va lui passer en arguments l’objet dont on souhaite tester le type et le type qui doit
servir de test. Cette fonction renverra True si l’objet est bien du type passé en second
argument ou si il est d’un sous-type dérivé de ce type ou False sinon.

La fonction issubclass() permet de tester l’héritage d’une classe, c’est-à-dire permet de


savoir si une classe hérite bien d’une autre classe ou pas. On va lui passer en arguments
la classe à tester ainsi qu’une autre classe dont on aimerait savoir si c’est une classe mère
de la classe passée en premier argument ou pas. La fonction renverra True si c’st le cas
ou False sinon.

Ces deux fonctions sont très utiles pour tester rapidement les liens hiérarchiques entre
certaines classes et objets et peuvent aider à comprendre plus facilement un script
complexe qui nous aurait été passé.
 

Le polymorphisme en Python orienté objet


“Polymorphisme” signifie littéralement “plusieurs formes”. Dans le contexte de la
programmation orientée objet, le polymorphisme est un concept qui fait référence à la
capacité d’une variable, d’une fonction ou d’un objet à prendre plusieurs formes, c’est-à-
dire à sa capacité de posséder plusieurs définitions différentes.

Pour bien comprendre ce concept, imaginons qu’on définisse une classe


nommée Animaux qui possède des fonctions comme seNourrir(), seDeplacer(), etc. Notre
classe va pouvoir ressembler à ça :

Ici, j’utilise un nouveau mot clef pass qui me sert à créer une fonction vide. En effet, le
mot clef pass ne fait strictement rien en Python. On est obligés de l’utiliser pour créer une
fonction vide car si on n’écrit rien dans notre fonction l’interpréteur Python va renvoyer
une erreur.
Ma classe Animaux dispose donc d’une fonction seDeplacer() qui ne contient pas
d’instruction. Maintenant, nous allons créer des sous-classes de Animaux pour différents
animaux : Chien, Aigle et Dauphin par exemple.

Ces trois sous classes vont par défaut hériter des membres de leur classe
mère Animaux et notamment de la méthode seDeplacer(). Ici, chacune de nos sous classes
va implémenter cette méthode différemment, c’est-à-dire va la définir différemment.

Pour ma classe Chien par exemple, la méthode seDeplacer() va renvoyer une valeur


“courir” tandis que pour Aigle cette méthode va renvoyer une valeur “voler”.
Pour Dauphin, seDeplacer() renverra “nager”.

Ceci est un exemple typique de polymorphisme : plusieurs sous-classes héritent d’une


méthode d’une classe de base qu’ils implémentent de manière différente.

Le polymorphisme permet également in-fine d’obtenir un code plus clair, plus lisible et
plus cohérent : on va pouvoir fournir des définitions de fonctions vides dans une classe
de base afin de laisser des sous-classes implémenter (définir) ces fonctions de
différentes manières.

Héritage multiple
Pour terminer cette leçon sur l’héritage et le polymorphisme, il faut savoir que Python
gère également une forme d’héritage multiple.

On parle d’héritage multiple en programmation orientée objet lorsqu’une sous-classe


peut hériter de plusieurs classes mères différentes.

Dans la pratique, l’héritage multiple est une chose très difficile à mettre en place au
niveau du langage puisqu’il faut prendre en charge les cas où plusieurs classes mères
définissent les mêmes variables et fonctions et définir une procédure pour indiquer de
quelle définition la sous-classe héritera.

En Python, dans la majorité des cas, l’héritage va se faire selon l’ordre des classes mères
indiquées et cela de manière récursive. Imaginons qu’une sous-classe AGrave hérite de
trois classes A, Accent et Abracadabra dans cet ordre et que la classe A hérite elle même
de la classe Alphabet tandis que Abracadabra hérite de Mot

On crée un objet en instanciant notre classe AGrave et on appelle une méthode depuis


notre objet. Python va à priori commencer par chercher la méthode dans AGrave, puis si
il ne la trouve pas cherchera dans A. S’il ne la trouve pas il cherchera ensuite
dans Alphabet, puis dans Accent, puis dans Abracadabra et finalement dans Mot.

Regardez plutôt le code suivant qui illustre bien cette situation :


En réalité, Python utilise un algorithme relativement complexe qui détermine l’ordre
d’appel (method resolution order, ou MRO en anglais) de manière dynamique, c’est-à-
dire en fonction des relations entre les différentes classes.

Dans notre exemple, si les classes A, Accent et Abracadabra avaient eu des parents en


commun, l’ordre aurait été beaucoup plus complexe à calculer. Ce genre de situations
arrive très peu fréquemment et est à éviter; un bon développeur privilégiant toujours la
lisibilité de son code et donc je n’en parlerai pas plus. Si vous souhaitez plus
d’informations à ce sujet, je vous invite à vous renseigner sur l’algorithme C3 utilisé par
Python pour déterminer le MRO.

Gérer la visibilité des membres de


classe en Python orienté objet
Dans cette nouvelle leçon liée à l’orienté objet, nous allons voir un autre concept
important de la POO qui concerne l visibilité ou le niveau d’accès des différents
membres de classe.
Nous terminerons cette leçon avec un petit rappel sur “pourquoi coder en orienté objet”
qui, je l’espère, vous permettra de commencer à avoir une vision d’ensemble claire sur la
programmation orientée objet et sur ses objectifs.

Les niveaux de visibilité des membres de


classe en programmation orientée objet
Dans la plupart des langages qui supportent l’orienté objet, on peut définir des “niveaux
de visibilité” ou “niveaux d’accès” pour les membres des classes (c’est-à-dire pour les
variables et les fonctions).

En POO, on distingue généralement trois niveaux de visibilité différents :

 Les membres privés auxquels on ne peut accéder que depuis l’intérieur de lac
classe ;
 Les membres protégés auxquels on ne peut accéder que depuis l’intérieur de la
classe ou depuis une classe fille ;
 Les membres publics auxquels on peut accéder depuis n’importe quelle instance
(ou objet) de la classe ou d’une classe fille.
Ces niveaux de visibilité permettent de “protéger” certains membres de classes qui ne
devraient pas être modifiés dans n’importe quelle situation ou depuis n’importe quel
endroit.

Les niveaux de visibilité des membres de


classe en Python
Python n’implémente pas directement ces concepts de visibilité des membres de classe
et il est donc impossible de définir un membre comme privé ou protégé : par défaut,
tous les membres de classe sont publics en Python.

En revanche, certaines conventions ont été mises en place par la communauté Python,
notamment au niveau des noms des membres de classe qui servent à indiquer aux
autres développeurs qu’on ne devrait accéder à tel membre que depuis l’intérieur de la
classe ou à tel autre membre que depuis la classe ou une classe fille.

Attention ici : ce ne sont que des conventions qui n’ont aucun équivalent réel en
Python : on va pouvoir informer d’autres développeurs du niveau de visibilité souhaité
pour un membre mais tous les membres seront toujours publics en Python et il est de la
responsabilité des autres développeurs de suivre nos indications ou pas.

Ces conventions sont les suivantes :

 On préfixera les noms des membres qu’on souhaite définir comme “privés” avec
deux underscores comme ceci : __nom-du-membre ;
 On préfixera les noms des membres qu’on souhaite définir comme “protégés”
avec un underscore comme ceci : _nom-du-membre.
Il est à noter que ces conventions n’ont pas été adoptées par hasard. En effet, Python
possède un mécanisme appelé “name mangling” qui fait que tout membre de classe
commençant par deux underscores, c’est-à-dire de la forme __nom-du-membre sera
remplacé textuellement lors de l’interprétation par _nom-de-classe__nom-du-membre.
Cela fait que si un développeur essaie d’utiliser un membre défini avec deux underscores
tel quel, Python renverra une erreur puisqu’il préfixera le nom avec un underscore et le
nom de la classe du membre.

Cette règle a été prévue par Python pour éviter les accidents de conflits entre plusieurs
membres de plusieurs classes qui auraient le même nom. Elle n’empêche pas d’accéder
ou de modifier un membre “privé”. En effet, il suffit de préfixer le membre de la même
façon que Python lors de son interprétation pour y accéder.

Prenons immédiatement un exemple afin de bien comprendre ce qu’on vient de dire :

On définit ici une classe Visibilite qui contient trois variables public, _protected et __private.


Notez qu’on pourrait aussi bien définir des fonctions de la même manière.

Maintenant, créons un objet à partir de cette classe et essayons d’afficher les valeurs de
nos variables de classe à partir de l’objet créé :
Comme vous le voyez, on accède sans souci à nos variables public et _protected. En
revanche, pour __private, le mécanisme de name mangling s’active et le nom passé est
préfixé par un underscore et le nom de la classe. On peut cependant contourner cela et
toujours afficher le contenu de la variable privée en utilisant la
notation _Visibiilite__private.

Il est possible que vous ne voyez pas l’intérêt de tout cela si vous n’avez pas beaucoup
d’expérience en programmation. Dans ce cas, il est important de retenir et de vous
persuader qu’une immense partie du travail d’un développeur est de s’assurer d’avoir un
code le plus clair, concis et modulable possible (en plus d’être fonctionnel bien
évidemment). Toutes ces notions liées à l’orienté objet permettent de servir ces objectifs.

Et si vous vous posez toujours la question : oui, on pourrait arriver à des résultats
similaires en utilisant une approche non orientée objet mais la qualité générale de notre
code serait bien plus mauvaise. De plus, Python nous fournit de nombreux outils et
notamment des méthodes pour les types prédéfinis qui ne sont accessible qu’en utilisant
l’orienté objet et il serait dommage de s’en priver.

Itérateurs et générateurs en Python


orienté objet
Les itérateurs permettent de parcourir des valeurs composites itérables (des objets
comme des listes par exemple). Les générateurs permettent de simplifier la création et
l’utilisation d’itérateurs. Dans cette nouvelle leçon, nous allons détailler le
fonctionnement des itérateurs Python et voir comment définir des générateurs.
 

Les itérateurs
“Itérer” signifie en français classique “répéter, faire une seconde fois”. Dans le contexte
de la programmation orienté objet, “itérer” sur un objet signifie parcourir l’objet attribut
par attribut pour accéder à leur valeur.

Les itérateurs sont implicitement utilisés chaque fois que nous manipulons des
collections de données comme les list, tuple ou string (qui sont des objets dits
“itérables”).
La méthode habituelle pour parcourir une collection est d’utiliser une boucle for.
Lorsque nous utilisons une boucle for pour parcourir un objet itérable, la boucle appelle
en fait en interne la fonction iter() sur l’objet itérable.

Au lieu d’utiliser la boucle for comme indiqué ci-dessus, nous pouvons utiliser la
fonction itérateur iter(). Un itérateur est un objet qui représente un flux de données. Il
retourne un élément à la fois.

La méthode intégrée Python iter() reçoit un itérable et retourne un objet itérateur. L’objet


itérateur renvoyé définit la méthode __next__() qui va accéder aux éléments de l’objet
itérable un par un.

Chaque fois que __next__() est appelée, l’élément suivant du flux itérateur est renvoyé.
Lorsqu’il n’y a plus d’éléments disponibles, __next__() lève une erreur StopIteration.

Notez qu’on peut également appeler la méthode __next__() manuellement en utilisant la


fonction next().
On va pouvoir définir nos propres itérateurs dans nos classes pour itérer de manière
particulière sur nos objets itérables (en partant de la fin, en sautant des caractères, etc.).

Pour cela, il suffit de définir une méthode __iter__() qui renvoie un objet disposant d’une
méthode __next__(). Si la classe définit elle-même la méthode __next__(),
alors __iter__() peut simplement renvoyer self.
Ici, on crée une classe qui définit un itérateur qui va sauter une donnée de la séquence
sur laquelle il Isère à chaque nouveau passage.

Les générateurs
La création d’itérateurs peut parfois s’avérer complexe ou contraignante. Les générateurs
sont des outils qui nous permettent de créer des itérateurs.

La syntaxe d’un générateur est la même que celle d’une fonction classique à la différence
que les générateurs utilisent l’instruction yield à la place de return pour retourner des
données.

L’instruction yield va mettre le générateur en pause mais le contexte d’exécution de


celui-ci va être conservé, ce qui va nous permettre d’itérer. A chaque fois qu’on appelle
un générateur avec next(), le générateur va reprendre son travail jusqu’au prochain yield.

Lorsqu’on définit un générateur, les méthodes __iter__() et __next__() sont créées


automatiquement. De plus, les variables locales ainsi que le contexte d’exécution sont
sauvegardés automatiquement entre les appels ce qui nous évite d’avoir à utiliser des
notations du type self.attribut. Enfin, les générateurs lèvent automatiquement une
exception StopIteration lorsqu’ils terminent leur exécution.

Ces fonctionnalités font des générateurs des outils privilégiés pour créer des itérateurs
de manière plus simple.
Annexe 2 : Quelques méthodes Python
utiles
En programmation orientée objet, tout élément d’un langage (ou presque) est objet. En
Python, les types de données sont en fait avant tout représenté par des classes qui
déterminent les propriétés et manipulations qu’on va pouvoir faire sur chaque donnée.
Lorsqu’on crée une liste, un dictionnaire, une chaine de caractères, etc. on crée avant
tout un nouvel objet à partir des classes list, dict, str, etc.

La plupart de ces classes définissent des méthodes qui permettent de réaliser des
opérations courantes sur chaque type de donnée. Dans cette leçon, nous allons passer
en revue quelques unes des méthodes qui pourront certainement vous être utiles par la
suite et qu’il faut connaitre pour les types de données str, list, et dict.
Pour obtenir la liste complète d’un méthode qu’on peut utiliser avec un type de
données, il suffit d’appeler la fonction dir() en lui passant un objet en argument.
Note : Les méthodes commençant et finissant par __ (un double underscore) sont
appelées des “méthodes magiques”. Ces méthodes fournissent des fonctionnalités
syntaxiques spéciales ou font des choses spéciales. Généralement, on ne va pas les
appeler directement.

Les méthodes des chaines de caractères


Les chaines de caractères Python disposent des méthodes magiques
suivantes : __add__(), __class__(), __contains__(), __delattr__(), __dir__(), __doc__(), __eq__(), _
_format__(), __ge__(), __getattribute__(), __getitem__(), __getnewargs__(), __gt__(), __hash__(), _
_init__(), __init_subclass__(), __iter__(), __le__(), __len__(), __lt__(), __mod__(), __mul__(), __ne
__(), __new__(), __reduce__(), __reduce_ex__(), __repr__(), __rmod__(), __rmul__(), __setattr__(), 
__sizeof__(), __str__(), __subclasshook__().

On va également pouvoir utiliser les méthodes classiques suivantes sur des objets
Python de
type str : capitalize(), casefold(), center(), count(), encode(), endswith(), expandtabs(), find(), format
(), format_map(), index(), isalnum(), isalpha(), isascii(), isdecimal(), isdigit(), isidentifier(), islower(), 
isnumeric(), isprintable(), isspace(), istitle(), isupper(), join(), ljust(), lower(), lstrip(), maketrans(), pa
rtition(), replace(), rfind(), rindex(), rjust(), rpartition(), rsplit(), rstrip(), split(), splitlines(), startswith(
), strip(), swapcase(), title(), translate(), upper(), zfill().

Parmi les méthodes qu’on va le plus utiliser, on peut mentionner les


méthodes lower(), upper() et capitalize() qui renvoient respectivement une chaine de
caractères en minuscules, majuscules, et avec la première lettre en majuscule.

La méthode replace() effectue un remplacement dans la chaine et renvoie la chaine


modifiée.

La méthode strip() permet de supprimer les espaces superflus en début et en fin de


chaine.

La méthode find() permet de chercher la première occurence d’un caractère ou d’une


séquence de caractères et renvoie leur position.
Les méthodes startswith() et endswith() permettent de vérifier si une chaine commence ou
se termine bien par un caractère ou par une séquence de caractères et renvoient un
booléen.
La méthode split() convertit une chaîne en une liste de sous-chaînes. On peut choisir le
caractère séparateur en le fournissant comme argument (par défaut l’espace est choisi
comme séparateur).

La méthode join() est la méthode “contraire” de split() : elle permet de rassembler un


ensemble de chaînes stockées dans un objet itérable (une liste, un tuple, un
dictionnaire…) en une seule.

Attention : la chaîne à laquelle on applique cette méthode est celle qui servira de
séparateur (un ou plusieurs caractères) ; l’argument transmis est la liste des chaînes à
rassembler. Si on lui passe un dictionnaire en argument, les valeurs retournées seront les
clefs du dictionnaire.

La méthode format() est une des méthodes qu’il faut absolument connaitre en Python.


Elle permet de formater des chaines de caractères. On va utiliser des accolades pour
définir des parties de chaines qui devront être formatées.
On va ensuite pouvoir utiliser la méthode format() pour formater la chaine en utilisant les
valeurs passées en argument.

On peut également utiliser les expressions formatées en utilisant des noms de variable et
en préfixant notre chaine avec la lettre f.

Les méthodes des listes


Les listes Python disposent des méthodes magiques
suivantes : __add__(), __class__(), __contains__(), __delattr__(), __delitem__(), __dir__(), __doc_
_(), __eq__(), __format__(), __ge__(), __getattribute__(), __getitem__(), __gt__(), __hash__(), __iad
d__(), __imul__(), __init__(), __init_subclass__(), __iter__(), __le__(), __len__(), __lt__(), __mul__
(), __ne__(), __new__(), __reduce__(), __reduce_ex__(), __repr__(), __reversed__(), __rmul__(), __
setattr__(), __setitem__(), __sizeof__(), __str__(), __subclasshook__().

Nous allons également pouvoir utiliser les méthodes suivantes avec les
listes : append(), clear(), copy(), count(), extend(), index(), insert(), pop(), remove(), reverse(), sort.

La méthode append() permet d’ajouter un ou une collection d’éléments en fin de liste. La


liste de départ est modifiée.
La méthode insert() permet elle d’ajouter un ou une collection d’éléments à une position
dans la liste. La position est spécifiée en premier argument tandis que l’élément à ajouter
est spécifié en second argument.

La méthode pop() retire et renvoie l’élément de la liste dont l’index est passé en


argument. Si on ne lui passe pas d’argument, le dernier élément sera supprimé.

La méthode remove() permet de supprimer le premier élément dont la valeur correspond


à la valeur passée en argument de cette méthode.

La méthode clear() permet de supprimer tous les éléments d’une liste.

La méthode sort() permet de classer les éléments d’une liste dans l’ordre alphabétique.


On peut lui passer un argument reverse = True pour que la liste soit classée dans l’ordre
alphabétique inversé (de Z à A).
 
Les méthodes des dictionnaires
Les dictionnaires disposent des méthodes magiques
suivantes : __class__(), __contains__(), __delattr__(), __delitem__(), __dir__(), __doc__(), __eq__(
), __format__(), __ge__(), __getattribute__(), __getitem__(), __gt__(), __hash__(), __init__(), __init
_subclass__(), __iter__(), __le__(), __len__(), __lt__(), __ne__(), __new__(), __reduce__(), __reduc
e_ex__(), __repr__(), __setattr__(), __setitem__(), __sizeof__(), __str__(), __subclasshook__().

Nous allons également pouvoir utiliser les méthodes suivantes avec ce type de
données : clear(), copy(), fromkeys(), get(), items(), keys(), pop(), popitem(), setdefault(), update(), 
values.

La méthode Python keys() renvoie la liste des clefs utilisées dans un dictionnaire tandis


que la méthode values() renvoie la liste des valeurs d’un dictionnaire. La
méthode get() renvoie elle la valeur de l’élément du dictionnaire possédant la clef
spécifiée.

La méthode items() extrait une liste de tuples à partir d’un dictionnaire.

Enfin, la méthode pop() supprime l’élément du dictionnaire lié à la clef spécifiée.


Les modules et paquets Python
Dans cette nouvelle partie, nous allons découvrir une autre facette du langage Python
qui en fait un langage à la fois très puissant, modulable et évolutif : l’utilisation de
modules. Nous allons notamment étudier le fonctionnement de quelques modules
prédéfinis qu’il convient de savoir manipuler.
 

Définition et cas d’utilisation des modules


Python
On appelle “module” tout fichier constitué de code Python (c’est-à-dire tout fichier avec
l’extension .py) importé dans un autre fichier ou script.

Les modules permettent la séparation et donc une meilleure organisation du code. En


effet, il et courant dans un projet de découper son code en différents fichiers qui vont
contenir des parties cohérentes du programme final pour faciliter la compréhension
générale du code, la maintenance et le travail d’équipe si on travaille à plusieurs sur le
projet.

En Python, on peut distinguer trois grandes catégories de module en les classant selon
leur éditeur :

 Les modules standards qui ne font pas partie du langage en soi mais sont
intégrés automatiquement par Python ;
 Les modules développés par des développeurs externes qu’on va pouvoir utiliser ;
 Les modules qu’on va développer nous mêmes.
Dans tous les cas, la procédure à suivre pour utiliser un mode sera la même. Nous allons
commencer par décrire cette procédure puis nous étudierons dans la suite de cette
partie quelques modules standards qu’il convient de connaitre.

Importer un module
Un programme Python va généralement être composé d’un script principal qui va
importer différents modules (c’est-à-dire différents fichiers Python) pour pouvoir les
utiliser.
Pour importer un module, on utilise la syntaxe import nom-de-mon-module. Pour utiliser les
éléments du module dans notre script, il faudra préfixer le nom de ces éléments par le
nom du module et un point. Cela permet d’éviter les conflits dans le cas où on aurait
défini des éléments de même nom que ceux disponibles dans le module.

Pour comprendre comment cela fonctionne en pratique, je vous invite à ouvrir votre
éditeur de texte et à créer un fichier qu’on va appeler “bonjour”. Notre fichier va contenir
une variable et une fonction comme ceci :

Ensuite, enregistrez le dans le dossier Python que vous devriez avoir créé au début de ce
cours et qui devrait se trouver sur votre bureau.

Dès que tout cela est fait, on peut retourner dans le terminal ou l’invite de commande.
Ne lancez pas l’interpréteur pour le moment et pensez bien à définir le dossier Python
comme dossier de référence pour la recherche de fichiers Python si ça n’a pas été fait au
début de ce cours.

Pour cela, vous pouvez utiliser la commande cd (pour “change directory”) suivie du


chemin du dossier qui doit être le dossier de référence (Desktop/Python pour Mac par
exemple).

On peut ensuite lancer l’interpréteur Python. Ici, il faut imaginer que notre terminal /
invite de commande représente le script principal de notre programme. On va importer
notre module dans ce script principal grâce à l’instruction import bonjour.

Lorsque l’interprète rencontre une instruction import, il importe le module s’il est présent
dans le path (le chemin de recherche). Pour rappel, le path ou chemin de recherche est
une liste de répertoires dans lesquels l’interpréteur cherche avant d’importer un module.
Pour être tout à fait précis, lorsqu’on importe un module, l’interpréteur Python le
recherche dans différents répertoires selon l’ordre suivant :

1. Le répertoire courant ;
2. Si le module est introuvable, Python recherche ensuite chaque répertoire listé
dans la variable shell PYTHONPATH ;
3. Si tout échoue, Python vérifie le chemin par défaut. Sous UNIX, ce chemin par
défaut est normalement /usr/local/lib/python/.
Dès que notre module est importé, on va pouvoir accéder tout simplement aux variables
et fonctions de notre module depuis notre script en préfixant le nom des éléments du
module par le nom du module et un point comme ceci :

Créer un alias de nom pour un module


On peut utiliser le mot clef as pour renommer un module ou plutôt pour créer un alias
de nom. Cela peut permettre d’obtenir des scripts plus courts et plus clairs dans le cas
où le nom du module est inutilement long ou s’il est peu descriptif.

Note : on ne peut importer un module qu’une fois dans un script. Si vous testez le code
ci-dessus et si vous aviez déjà importé le module précédemment, il faudra que vous
quittiez l’interpréteur et que vous le relanciez pour que tout fonctionne. Pour quitter
l’interpréteur, vous pouvez utiliser l’instruction quit().

Importer uniquement certains éléments


d’un module
Parfois, nous n’aurons besoin que de certains éléments précis dans un module. On va
alors pouvoir se contenter d’importer ces éléments en particulier. Pou cela, on va utiliser
l’instruction from nom-du-module import un-element.

On va par exemple pouvoir choisir de n’importer que la variable nom ou que la


fonction disBonjour() depuis le module bonjour.py.

Dans le cas où on n’importe que certains éléments depuis un module, il ne faudra pas
ensuite préfixer le nom des éléments par le nom du module pour les utiliser dans notre
script principal.
 

Obtenir la liste des éléments d’un module


Souvent, on importera des modules standards ou créés par d’autres développeurs. Dans
ce cas là, il peut être intéressant d’obtenir rapidement la liste des éléments du module
afin de voir rapidement ce qui va pouvoir nous être utile.

Pour faire cela, on peut utiliser la fonction dir() qui renvoie la liste de toutes les fonctions
et variables d’un module.

Comme vous pouvez le voir, tout fichier Python possède par défaut des éléments de
configuration.

 
Les modules Python standards
Comme je vous l’ai dit au début de cette leçon, nous importerons bien souvent des
modules créés par d’autres développeurs ou des modules mis à notre disposition par
Python lui même.

En effet, il existe un grand nombre de modules préconçus et prêts à l’emploi qui sont
fournis d’office avec Python. Ces modules vont étendre le langage et nous permettre de
réaliser toutes sortes d’opérations notamment grâce aux fonctions qu’ils nous
fournissent.

Pour importer un module Python, nous allons à nouveau tout simplement utiliser une
instruction import comme si on importait l’un de nos modules.

Les modules Python standards à connaitre sont les suivants :

 Le module cgi (“Common Gateway Interface” ou “Interface de Passerelle


Commune” en français) fournit des éléments permettant à des programmes
Python de s’exécuter sur des serveurs HTTP ;
 Le module datetime fournit des classes pour manipuler de façon simple ou plus
complexe des dates et des heures ;
 Le module json permet l’encodage et le décodage de données au format JSON ;
 Le module math fournit un ensemble de fonctions permettant de réaliser des
calculs mathématiques complexes ;
 Le module os fournit une manière portable d’utiliser les fonctionnalités
dépendantes du système d’exploitation ;
 Le module pickle permet de sérialiser des objets Python ;
 Le module random implémente des générateurs de nombres pseudo-aléatoires
pour différentes distributions ;
 Le module re fournit des opérations sur les expressions rationnelles similaires à
celles que l’on trouve dans Perl ;
 Le module socket fournit un accès à l’interface sockets qui correspond à un
ensemble normalisé de fonctions de communication ;
 Le module sys fournit un accès à certaines variables système utilisées et
maintenues par l’interpréteur, et à des fonctions interagissant fortement avec ce
dernier ;
 Les modules urllib.request et urllib.parse permettent d’ouvrir, de lire et d’analyser
des URLs.
Vous pouvez retrouver la liste complète des modules standards Python sur le site officiel.
 

Les paquets Python


Un paquet est tout simplement un ensemble de plusieurs modules regroupés entre eux.
On va pouvoir importer des paquets de la même façon que des modules et accéder à un
module ou à un élément en particulier en utilisant la syntaxe nom-paquet.nom-module.nom-
element.

Modules Python standards Math,


Random et Statistics
Dans cette leçon, nous allons passer en revue rapidement les trois modules Python
standards math, random et statistics et découvrir leurs fonctionnalités les plus utilisées.
 

Le module math
Le module math nous fournit un accès à de nombreuses fonctions permettant de réaliser
des opérations mathématiques comme le calcul d’un sinus, cosinus, d’une tangente, d’un
logarithme ou d’une exponentielle.

Les fonctions les plus couramment utilisées sont les suivantes :

 Les fonctions ceil() et floor() renvoient l’arrondi du nombre passé en argument en


arrondissant respectivement à l’entier supérieur et inférieur ;
 La fonction fabs() renvoie la valeur absolu d’un nombre passé en argument ;
 La fonction isnan() renvoie True si le nombre passé en argument est NaN = Not a
Number (pas un nombre en français) ou False sinon ;
 La fonction exp() permet de calculer des exponentielles ;
 La fonction log() permet de calculer des logarithmes ;
 La fonction sqrt() permet de calculer la racine carrée d’un nombre ;
 Les fonctions cos(), sin() et tan() permettent de calculer des cosinus, sinus et
tangentes et renvoient des valeurs en radians.
Attention : les fonctions de ce module ne peuvent pas être utilisées avec des nombres
complexes. Pour cela, il faudra plutôt utiliser les fonctions du module cmath.
Le module math définit également des constantes mathématiques utiles comme pi ou le
nombre de Neper, accessibles via math.pi et math.e.

Pour obtenir la liste complète des fonctions et constantes de ce module, je vous invite à
consulter la documentation.

Le module random
Le module random nous fournit des outils pour générer des nombres pseudo-aléatoires
de différentes façons.

La fonction random() est le plus utilisée du module. Elle génère un nombre à virgule


flottante aléatoire de façon uniforme dans la plage semi-ouverte [0.0, 1.0).

La fonction uniform() va elle générer un nombre à virgule flottante aléatoire compris dans


un intervalle. On va lui passer deux tombes en argument : le premier nombre représente
la borne basse de l’intervalle tandis que le second représente la borne supérieure. Notez
que cette fonction se base sur random().
Le module random est très riche et contient de nombreuses fonctions qui vont nous
permettre de générer des nombres pseudo aléatoires de différentes manières et pour
différentes situations. Je vous invite à les découvrir en détail dans la documentation.

Le module statistics
Le module statistics nous fournit des outils nous permettant d’effectuer des calculs de
statistiques peu complexes, comme des calculs de moyenne, de médiane ou de variance.

Ce module contient notamment les fonctions suivantes :

 La fonction mean() permet de calculer une moyenne ;


 La fonction median() permet de calculer une médiane ;
 La fonction variance() permet de calculer une variance ;
 La fonction stdev() permet de calculer un écart type.
Vous pouvez consulter la liste complète des fonctions de ce module ici.

Les modules Python standards Datetime,


Time et Calendar
En programmation, nous sommes souvent amenés à manipuler des dates qui sont des
objets complexes. Python facilite le travail avec les dates en fournissant l’accès à des
modules dont datetime, time et calendar que nous allons étudier dans cette leçon.
 

Le module Python standard datetime


Le module datetime est le module de référence pour manipuler les dates et le temps. Il
nous fournit notamment des classes date et time qui vont nous être précieuses.

Python distingue deux sorte d’objets date et time : les objets “avisés” et les objets
“naifs”. Un objet avisé est un objet qui possède suffisamment de connaissances internes
pour se situer de façon relative par rapport à d’autres objets avisés. Un objet naïf ne
comporte pas assez d’informations pour se situer sans ambiguïté par rapport à d’autres
objets date ou time.
Ici, vous pouvez tenir que les objets avisés datetime et time ont un attribut optionnel
d’information sur le fuseau horaire nommé tzinfo. Cet attribut ou objet tzinfo capture
l’information à propos du décalage avec le temps UTC, le nom du fuseau horaire, et si
l’heure d’été est effective.

Le module datetime définit les types suivants :

 date : représente une date; possède des attributs year, month et day ;


 time : représente un temps; possède des
attributs hour, minute, second, microsecond et tzinfo ;
 datetime : combinaison d’une date et d’un temps; possède des
attributs year, month, day, hour, minute, second, microsecond et tzinfo;
 timedelta : représente la différence entre deux objets date, time ou datetime exprimée
en microsecondes ;
 tzinfo : classe de base abstraite (= qui ne peut pas directement être instanciée)
pour les objets portants des informations sur les fuseaux horaires ;
 timezone : classe qui implémente la classe abstraite <code<tzinfo< code=""
style="box-sizing: inherit;">.</code<tzinfo<>
Chaque type (c’est-à-dire chaque classe) va posséder ses fonctions et variables qui vont
nous permettre d’effectuer telle ou telle manipulation sur des dates, rendant le
module datetime très complet.

Voici quelques manipulations courantes qu’on va pouvoir effectuer à partir des classes
du module datetime :
Pour une référence complète sur le module Python datetime, je vous invite à consulter
la documentation.
 

Le module Python standard time


Le module Python time fournit différentes fonctions liées au temps. Il peut et est
généralement utilisé conjointement avec le module datetime. Attention ici à ne pas
confondre le module time et la classe time du module datetime.

Le module time possède à nouveau de nombreuses fonctions. Nous allons rapidement


passer en revue les fonctions les plus utilisées. Une nouvelle fois, je vous invite à
consulter la documentation pour plus d’informations sur ce module.

La fonction time() renvoie le temps en secondes depuis epoch sous forme de nombre à


virgule flottante.

L’epoch correspond au point de départ du temps utilisé comme référence par votre OS.
Il dépend donc de la plate-forme. Pour Unix, epoch est le 1er janvier 1970 à 00:00:00
(UTC). Pour savoir comment est définie epoch sur une plate-forme donnée, il suffit
d’appeler time.gmtime(0).

La fonction gmtime() convertit un temps (passé en argument) exprimé en secondes


depuis epoch en un struct_time au format UTC dans lequel le drapeau dst est toujours
égal à zéro. Si aucun argument ne lui est fourni, l’heure actuelle telle que renvoyée
par time() sera utilisée.

Le DST (Daylight Saving Time) correspond à l’heure d’été, un ajustement du fuseau


horaire d’une heure (généralement) pendant une partie de l’année. Les règles de DST
sont magiques (déterminées par la loi locale) et peuvent changer d’année en année.

Le struc_time correspond au type de la séquence de valeur temporelle renvoyé


par gmtime(), localtime() et strptime(). Ses valeurs sont accessibles par index et par nom
d’attribut. Les valeurs suivantes sont possibles :

Index Nom de l’attribut Ex de valeur

0 tm_year 2000, 2010, 2019


Index Nom de l’attribut Ex de valeur

1 tm_mon plage [1, 12]

2 tm_mday plage [1, 31]

3 tm_hour plage [0,23]

4 tm_min plage [0,59]

5 tm_sec plage [0,61]

6 tm_wday plage [0, 6], Lundi valant 0

7 tm_yday plage [1, 366]

8 tm_isdst 0, 1 ou -1

– tm_zone abréviation du nom du fuseau horaire

– tm_gmtoff décalage à l’est de UTC en secondes

La fonction localtime() est similaire à gmtime() mais convertit le résultat en heure locale.


On peut lui passer un nombre de secondes représentant une date en argument. Si aucun
argument ne lui est fourni, l’heure actuelle telle que renvoyée par time() sera utilisée.
La fonction mktime() est la fonction inverse de localtime(). Son argument est soit
un struct_time soit un 9-tuple.

La fonction strptime() analyse une chaîne passée en premier argument représentant une


heure selon un format passé en second argument. La valeur renvoyée est une
valeur struct_time telle que renvoyée par gmtime() ou localtime().

La fonction strftime() convertit un tuple ou une donnée struct_time passé en second


argument en une chaîne. Le format de la chaine est spécifié par le premier argument
passé à la fonction. Si le temps n’est pas fourni, l’heure actuelle renvoyée
par localtime() est utilisée.

Les directives suivantes peuvent être utilisées dans la chaîne format :

Directive Signification

%a Nom abrégé du jour de la semaine selon les paramètres régionaux.

%A Le nom de semaine complet de la région.

%b Nom abrégé du mois de la région.

%B Nom complet du mois de la région.

Représentation appropriée de la date et de l’heure selon les paramètres


%c
régionaux.

%d Jour du mois sous forme décimale [01,31].

%H Heure (horloge sur 24 heures) sous forme de nombre décimal [00,23].

%I Heure (horloge sur 12 heures) sous forme de nombre décimal [01,12].


Directive Signification

%j Jour de l’année sous forme de nombre décimal [001,366].

%m Mois sous forme décimale [01,12].

%M Minutes sous forme décimale [00,59].

%p L’équivalent local de AM ou PM.

%S Deuxième sous forme de nombre décimal [00,61].

Numéro de semaine de l’année (dimanche en tant que premier jour de la


semaine) sous forme décimale [00,53]. Tous les jours d’une nouvelle année
%U
précédant le premier dimanche sont considérés comme appartenant à la
semaine 0.

%w Jour de la semaine sous forme de nombre décimal [0 (dimanche), 6].

Numéro de semaine de l’année (lundi comme premier jour de la semaine)


%W sous forme décimale [00,53]. Tous les jours d’une nouvelle année précédant le
premier lundi sont considérés comme appartenant à la semaine 0.

%x Représentation de la date appropriée par les paramètres régionaux.

%X Représentation locale de l’heure.


Directive Signification

%y Année sans siècle comme un nombre décimal [00, 99].

%Y Année complète sur quatre chiffres.

Décalage de fuseau horaire indiquant une différence de temps positive ou


négative par rapport à UTC / GMT de la forme +HHMM ou -HHMM, où H
%z
représente les chiffres des heures décimales et M, les chiffres des minutes
décimales [-23:59, +23:59].

%Z Nom du fuseau horaire (pas de caractères s’il n’y a pas de fuseau horaire).

%% Un caractère '%' littéral.
 

Le module Python standard calendar


Le module Python calendar permet d’afficher un calendrier et fournit des fonctions
relatives au calendrier.

Ce module définit une classe Calendar qui va permettre de créer des objets de type


calendrier et une classe TextCalendar qui peut être utilisée pour générer des calendriers
en texte brut.

Les calendriers sont des objets très spécifiques qu’on ne manipule pas tous les jours et je
n’irai donc pas plus loin dans la présentation de ce module. Si vous avez besoin un jour
de créer un calendrier, sachez simplement que ce module existe. Vous pourrez trouver
toutes les informations relatives aux calendriers Python sur la documentation officielle
du module.

Le module Python standard Re et


l’utilisation des expressions régulières
ou rationnelles
Dans cette leçon, nous allons nous intéresser aux expressions rationnelles et au module
Python standard re qui nous permet de les utiliser. Cette leçon n’est pas un cours sur les
expressions rationnelles qui représentent un sujet vaste et complexe mais simplement
une introduction aux possibilités et à l’utilisation de ces expression dans un contexte
Python.
 

Présentation des expressions régulières ou


expressions rationnelles
Les expressions régulières ou expressions rationnelles ne font pas partie du langage
Python en soi mais constituent un langage à part. Python nous permet d’exploiter leur
puissance et fournit un support pour les expressions régulières via son module
standard re.

Les expressions régulières sont des schémas ou des motifs utilisés pour effectuer des
recherches et des remplacements dans des chaines de caractères.

Ces schémas ou motifs sont tout simplement des séquences de caractères dont certains
vont disposer de significations spéciales et qui vont nous servir de schéma de recherche.
On les appelle également des masques de recherche.

Concrètement, les expressions régulières vont nous permettre de vérifier la présence de


certains caractères ou suites de caractères dans une expression afin de valider la forme
de données envoyées par l’utilisateur via une fonction input() par exemple.

 
La syntaxe des expressions rationnelles
Une expression rationnelle est représentée par un motif de recherche. Ce motif de
recherche va pouvoir être comparée à une ou plusieurs chaines pour déterminer les
correspondances.

Un motif de recherche peut être composés de caractères “normaux”, c’est-à-dire des


caractères qui ne représentent qu’eux mêmes et de caractères “spéciaux”, c’est-à-dire
des caractères qui possèdent une signification spéciale et vont nous permettre de
rechercher autre chose qu’eux mêmes. On appelle également ces caractères au sens
spécial des “métacaractères”.

Ces caractères spéciaux font toute la puissance des expressions rationnelles puisqu’ils
nous permettent de créer des motifs de recherche très précis et complexes.

Le premier caractère à connaitre est l’antislash \ qui est utilisé par les expressions
rationnelles pour donner un sens spécial à certains caractères normaux ou au contraire
pour neutraliser (“échapper”) le sens d’un caractère spécial et nous permettre de
rechercher le caractère en soi sans qu’il exprime son sens spécial.

Ici, nous sommes déjà confrontés à un souci puisque Python utilise également l’antislash
comme caractère d’échappement. Pour rechercher un antislash littéral avec une
expression régulière il faudrait donc écrire \\\\ puisque chaque antislash doit être
représenté par \\ dans une chaine littérale Python et que pour rechercher un antislash
(qui est un caractère spécial) dans une expression rationnelle il faut écrire \\ (le premier
antislash servant de caractère d’échappement pour rechercher le deuxième).

Pour éviter ce genre de situation, on utilisera une notation Python de chaines brutes
plutôt que littérales. Pour cela, il suffira de préfixer la chaine avec un r.

Ensuite, vous devez savoir que certains caractères ne vont avoir un sens spécial qu’en
dehors de ce qu’on appelle des classes de caractères ou vont pouvoir avoir des sens
spéciaux différents selon qu’ils soient dans des classes de caractères ou en dehors.
Commençons déjà par comprendre ce qu’est une classe de caractères.

 
Les classes de caractères
Les classes de caractères vont nous permettre de fournir différents choix de
correspondance pour un caractère en spécifiant un ensemble de caractères qui vont
pouvoir être trouvés.

En d’autres termes, elles vont nous permettre de rechercher n’importe quel caractère
d’une chaine qui fait partie de la classe de caractères fournie dans le masque, ce qui va
rendre les expressions régulières déjà beaucoup plus puissantes et flexibles qu’une
recherche classique.

Pour déclarer une classe de caractères dans notre masque de recherche, nous allons
utiliser une paire de crochets [ ] qui vont nous permettre de délimiter la classe en
question.

Dans le langage des expressions régulières, de nombreux caractères vont avoir une
signification spéciale et vont nous permettre de signifier qu’on recherche tel caractères
ou telle séquence de caractères un certain nombre de fois ou à une certaine place dans
une chaine.

Au sein des classes de caractères, seuls les caractères suivants possèdent une
signification spéciale :

Métacaractère Description

Caractère de protection ou d’échappement qui va avoir plusieurs usages


(on va pouvoir s’en servir pour donner un sens spécial à des caractères
\
qui n’en possèdent pas ou au contraire pour neutraliser le sens spécial
des métacaractères).

Si placé au tout début d’une classe, permet de nier la classe c’est-à-dire


^
de chercher tout caractère qui n’appartient pas à la classe.

– Entre deux caractères, permet d’indiquer un intervalle de caractères


(correspond à écrire les deux caractères et tous les caractères entre ces
Métacaractère Description

deux là).

Si on souhaite rechercher le caractère représenté par l’un des métacaractères ci-dessus


plutôt que de l’utiliser pour son sens spécial (par exemple si on souhaite rechercher le
signe moins), il faudra alors le protéger ou « l’échapper » avec un antislash.

Notez qu’il faudra également protéger les caractères de classe (les crochets) si on
souhaite les inclure pour les rechercher dans une classe de caractères car dans le cas
contraire on n’aurait aucun moyen de déterminer si le caractère “]” est recherché ou si la
classe est refermée par exemple.

Les classes de caractères abrégées


En plus des classes de caractères “classiques”, les expressions régulières possèdent
également des éléments qu’on appelle classes de caractères abrégées et qui permettent
de représenter certaines classes couramment utilisées avec une syntaxe très courte.

La syntaxe des classes abrégées utilise l’antislash suivi d’un caractère “normal” afin de lui
donner dans un cas une signification spéciale. Les classes abrégées les plus intéressantes
sont les suivantes (faites bien attention aux emplois de majuscules et de minuscules
ici !) :

Classe
Description
abrégée

Représente tout caractère de « mot » (caractère alphanumérique + tiret


\w
bas). Équivalent à [a-zA-Z0-9_]

\W Représente tout caractère qui n’est pas un caractère de « mot ». Equivalent


Classe
Description
abrégée

à [^a-zA- Z0-9_]

\d Représente un chiffre. Équivalent à [0-9]

\D Représente tout caractère qui n’est pas un chiffre. Équivalent à [^0-9]

\s Représente un caractère blanc (espace, retour chariot ou retour à la ligne)

\S Représente tout caractère qui n’est pas un caractère blanc

\t Représente une espace (tabulation) horizontale

\v Représente une espace verticale

\n Représente un saut de ligne

Les caractères spéciaux en dehors des classe


de caractères
En dehors des classes de caractères, nous avons accès à de nombreux autres caractères
au sens spécial. En voici la liste ainsi que leur signification :
Métacaractère Représente

. N’importe quel caractère

^ Le début d’une chaine ou d’une ligne

$ La fin d’une chaine ou d’un ligne

| Une alternative : correspond au caractère à droite ou à gauche

* 0, 1 ou plusieurs occurrences

+ 1 ou plusieurs occurrences

? 0 ou 1 occurrence

Un quantificateur : correspond à un nombre n d’occurences d’un


{…}
caractère

Une classe de caractères : tous les caractères énumérés dans la classe,


[…]
avec possibilité de plages dont les bornes sont séparées par « -« 

Un groupe de capture : utilisée pour limiter la portée d’un masque ou


(…)
d’une alternative

Note : les expressions rationnelles possèdent également des éléments de syntaxe plus
complexes comme les assertions que nous n’étudierons pas dans ce cours.

 
Le module Python re et ses fonctions
Maintenant que nous avons (très rapidement) parcouru les éléments de syntaxe
principaux des expressions régulières, il est temps de les utiliser avec le module re de
manière pratique.

Une expression rationnelle en soi n’est qu’un motif. Nous allons donc utiliser des
fonctions qui vont permettre d’effectuer des recherches de motifs dans des chaines, des
remplacements, etc.

La fonction compile() compile un motif vers une expression rationnelle compilée qu’on va


pouvoir utiliser avec les méthodes match() et search().

On utilisera compile() lorsqu’on voudra sauvegarder une expression rationnelle pour la


réutiliser dans un programme.

La fonction search() permet d’analyser une chaine passée en deuxième argument à la


recherche du premier emplacement où l’expression rationnelle passé en premier
argument trouve une correspondance, et renvoie l’objet de correspondance trouvé
ou None si aucune position dans la chaîne ne valide le motif.

La fonction match() prend également un schéma de recherche en premier argument et


une chaine dans laquelle effectuer la recherche en deuxième argument et renvoie l’objet
de correspondance trouvé si zéro ou plus caractères au début de la chaine
correspondent à l’expression rationnelle ou None si la chaîne ne correspond pas au motif.

La fonction findall() renvoie toutes les correspondances de l’expression régulière passée


en premier argument dans la chaine passée en deuxième argument qui ne se
chevauchent pas, sous forme d’une liste de chaînes. Le chaîne est analysée de la gauche
vers la droite, et les correspondances sont renvoyées dans l’ordre où elles sont trouvées.
Introduction à la manipulation de
fichiers en Python
Dans cette nouvelle partie, nous allons découvrir un nouveau moyen de stocker des
données de façon durable pour les manipuler par la suite en les stockant dans des
fichiers.
 
Le stockage des données : variables, fichiers,
bases de données
Jusqu’à présent, nous avons utilisé des variables pour stocker des données sous forme
de chaines, de listes, de dictionnaires, etc.

Les variables sont très pratiques car elles vont nous permettre de manipuler nos
données très facilement en Python. Cependant, elles ne vont pas toujours être les outils
les mieux adaptés pour stocker des données.

En effet, le gros “défaut” des variables est qu’elles ne peuvent stocker une information
que temporairement (au mieux le temps de l’exécution d’un script).

Or, dans certains cas, on aimerait enregistrer des informations de manière définitives,
notamment lorsqu’il s’agit d’informations envoyées par les utilisateurs.

De plus, les variables ne sont pas adaptées pour le stockage de nombreuses données.

En programmation, pour stocker des informations de manière définitive, on va pouvoir


soit enregistrer ces informations dans des fichiers, soit les enregistrer dans des bases de
données.

De manière générale, les bases de données sont plus puissantes et plus performantes
que le recours aux fichiers pour stocker des informations mais la gestion d’une base de
données est beaucoup plus complexe que l’utilisation de fichiers.

Nous utiliserons donc les fichiers pour des programmes aux ambitions plus modestes et
lorsqu’on n’aura pas de trop grosses quantités d’informations à stocker et au contraire
les bases de données lorsque le besoin d’une structure plus robuste se fera sentir.

Ouvrir un fichier en Python avec fopen()


Nous allons pouvoir effectuer toutes sortes de manipulations sur nos fichiers en Python :
création d’un fichier, lecture des données, écriture, etc. Pour réaliser ces opérations, il va
cependant avant tout falloir ouvrir le fichier. Pour cela, on utilise la fonction fopen().

La fonction fopen() renvoie un objet de type “fichier” (type file en anglais). Cette fonction


nous permet d’ouvrir un fichier pour y réaliser différentes opérations.

On va passer deux arguments à la fonction fopen() : le nom du fichier à ouvrir et le mode


d’ouverture (qui est par défaut r). Ce mode d’ouverture va conditionner les opérations
qui vont pouvoir être faites sur le fichier par la suite. Les modes d’ouverture les plus
utilisés et qui vont nous intéresser sont les suivants :

Mode
Description
d’ouverture

Ouvre un fichier en lecture seule. Il est impossible de modifier le fichier.


r
Le pointeur interne est placé au début du fichier.

Ouvre un fichier en lecture et en écriture. Le pointeur interne est placé au


r+
début du fichier.

Ouvre un fichier en écriture seule en conservant les données existantes.


a Le pointeur interne est placé en fin de fichier et les nouvelles données
seront donc ajoutées à la fin. Si le fichier n’existe pas, le crée.

Ouvre un fichier en lecture et en écriture en conservant les données


a+ existantes. Le pointeur interne est placé en fin de fichier et les nouvelles
données seront donc ajoutées à la fin. Si le fichier n’existe pas, le crée.

Ouvre un fichier en écriture seule. Si le fichier existe, les informations


w
existantes seront supprimées. S’il n’existe pas, crée un fichier.

w+ Ouvre un fichier en lecture et en écriture. Si le fichier existe, les


informations existantes seront supprimées. S’il n’existe pas, crée un
Mode
Description
d’ouverture

fichier.

Notez qu’on va également pouvoir rajouter une autre lettre derrière le mode pour
définir si le fichier doit être ouvert en mode texte (lettre t, valeur par défaut ou en mode
binaire (lettre b). Dans ce cours, nous nous concentrerons sur le mode texte et
n’aborderons pas le mode binaire, généralement moins utilisé.

Fermer un fichier
Une fois qu’on a terminé de manipuler un fichier, il est considéré comme une bonne
pratique de le fumer. Cela évite d’utiliser des ressources inutilement et d’obtenir certains
comportements inattendus.

Pour fermer un fichier, on peut soit utiliser la méthode close() soit idéalement ajouter le


mot clef with avant open() lors de l’ouverture du fichier qui garantira que le fichier sera
fermé automatiquement une fois les opérations terminées.

La position du curseur interne ou pointeur


Avant d’aller plus loin dans la manipulation de fichier, il faut que je vous parle de la
position du curseur (ou « pointeur de fichier ») car celle-ci va impacter le résultat de la
plupart des manipulations qu’on va pouvoir effectuer sur les fichiers. Il est donc essentiel
de toujours savoir où se situe ce pointeur et également de savoir comment le bouger.

Le curseur ou pointeur est l’endroit dans un fichier à partir duquel une opération va être
faite. Pour donner un exemple concret, le curseur dans un document Word, dans un
champ de formulaire ou lorsque vous effectuez une recherche Google ou tapez une URL
dans votre navigateur correspond à la barre clignotante.
Ce curseur indique l’emplacement à partir duquel vous allez écrire votre requête ou
supprimer un caractère, etc. Le curseur dans les fichiers va être exactement la même
chose à la différence qu’ici on ne peut pas le voir visuellement.

Le mode d’ouverture choisi va être la première chose qui va influer sur la position du
pointeur. En effet, selon le mode choisi, le pointeur de fichier va se situer à une place
différente. Ensuite, il faut savoir que certaines méthodes vont déplacer ce curseur lors de
leur exécution, comme les méthodes de lecture du fichier par exemple.

Pour connaitre la place du pointeur interne dans un fichier et déplacer ce pointeur, nous
allons pouvoir utiliser les méthodes tell() et seek().

La méthode tell() renvoie la position du pointeur interne. La méthode seek() permet de


repositionner ce pointeur.

La méthode fseek() prend deux arguments : le premier argument indique de combien ou


souhaite décaler le curseur interne tandis que le second argument indique le point de
référence à partir d’où décaler le pointeur. Ce point de référence peut être soit égal à 0
pour le début du fichier, 1 pour la position actuelle ou 2 pour la fin du fichier.

Cependant, lorsque le fichier est ouvert en mode texte, la méthode seek() ne va nous


offrir que des possibilités limitées.

Entre autre, seek() ne va accepter comme valeur de décalage que 0 ou la valeur renvoyée


par tell() et le point de référence ne pourra être que le début ou la fin du fichier.

Opérations sur les fichiers en Python


Dans cette leçon, nous allons apprendre à effectuer toutes sorte d’opérations avec nos
fichiers : écriture dans un fichier, lecture des données d’un fichier, suppression d’un
fichier, etc.
 

Ecrire dans un fichier en Python


Pour insérer des données dans un fichier, c’est-à-dire pour écrire dans un fichier, on
utilisera la méthode write(). On va passer les données à insérer en argument de write().
Cette méthode n’accepte que des données de type chaines de caractères : pensez donc
bien à convertir vos données au bon format avant tout.

De plus, notez bien que les données seront écrites à partir de la position du curseur
interne et que si celui-ci est situé au début ou au milieu du fichier les nouvelles données
écraseront les anciennes.

Finalement, notez également que write() va renvoyer le nombre de caractères écrits.

Utilisons immédiatement write() pour écrire le contenu d’une variable dans un fichier :

Lire les données d’un fichier en Python


Il existe plusieurs façons de lire un fichier en Python. On va pouvoir lire le fichier
entièrement, lire seulement une certaine partie du fichier ou lire le fichier ligne par ligne.
Dès qu’on lit dans un fichier, le curseur interne est déplacé jusqu’au point de fin de
lecture.

Pour lire entièrement un fichier, on peut utiliser la méthode read() sans argument. Cette


méthode renverra le contenu du fichier sous forme de chaine de caractères.

Pour ne lire qu’une partie d’un fichier, on peut passer un nombre en argument
à read() qui lui indiquera combien de caractères lire à partir de la position courante du
pointeur interne.
Enfin, pour ne lire qu’une ligne d’un fichier, on peut utiliser la méthode readline().

On peut effectuer différentes opérations sur un fichier à la suite comme par exemple le
créer, écrire dedans puis lire les informations qu’il contient avec la syntaxe suivante.
Attention à la position du curseur !

On peut également ouvrir un fichier et écrire dedans puis le refermer et le réouvrir plus
tard pour lire les informations qu’on contient. Dans l’exemple ci-dessous, je n’utilise
plus with ni as. Je place les informations d’ouverture dans une variable. Il ne faudra pas
oublier de fermer le fichier manuellement dans ce cas avec close() dès nos opérations
terminées.
 

Vérifier l’existence d’un fichier


Pour vérifier l’existence d’un fichier, on peut utiliser la fonction exists() du
module path qui appartient au module Python standard os. Cette fonction renvoie True si
le chemin du fichier passé est un chemin qui existe ou False sinon.

On va pouvoir utiliser cette fonction pour vérifier si un fichier existe et le créer si ce n’est
pas le cas :

Supprimer un fichier
Pour supprimer un fichier, on peut utiliser la fonction remove() du module Python os. On
va passer le chemin du fichier à supprimer en argument de celle-ci.
Ici, on teste si le fichier a bien été supprimé en observant si exists() renvoie bien False ou
pas (note l’utilisation de l’opérateur logique inverse not en début de condition if).

L’échange de données en Python avec


le module Json
Dans cette leçon, nous allons brièvement présenter un format d’échange de données
extrêmement connu dans le monde de la programmation appelé JSON (JavaScript
Object Notation) et voir comment on peut l’utiliser pour échanger des données Python
ou pour recevoir des données JSON et les convertir en données Python.
 

Présentation de JSON
JSON (JavaScript Object Notation) est un format d’échange de données dont la syntaxe
s’inspire des objets littéraux JavaScript bien que JSON n’appartienne pas au JavaScript.
JSON peut représenter des nombres, des booléens, des chaînes, la valeur null, des
séquences de valeurs ordonnées, des objets, etc. JSON ne représente pas nativement
des types de données plus complexes tels que des fonctions, des expressions régulières,
des dates, etc.

La légèreté, la simplicité et les performances de cette notation ont fait de JSON le


standard pour l’échange de données. De nombreux langages -dont Python- proposent
donc aujourd’hui leurs fonctions pour transformer des données en JSON et inversement.

Le format de données JSON


JSON est un format d’échange de données pensé pour gérer deux structures de données
universelles :

 Une collection de paires nom / valeur. Dans les différentes langages, ce type de
structure peut s’appeler objet, enregistrement, dictionnaire, table de hachage,
liste à clé ou tableau associatif.
 Une liste ordonnée de valeurs. Dans la plupart des langages, c’est ce qu’on va
appeler tableau, liste, vecteur ou séquence.
En JSON, ces deux structures se retrouvent sous les formes suivantes :

 Un objet est un ensemble non ordonnées de paires nom : valeur. Un objet


commence avec { et se termine avec }. Les noms sont suivis de : et les
paires nom : valeur sont séparées par des ,
 Un tableau est une collection ordonnée de valeurs. Un tableau commence
avec [ et se termine avec ]. Les valeurs sont séparées par des ,
Une valeur peut être une chaine de caractères entourées par des guillemets doubles, un
nombre, un booléen, la valeur null, un objet ou un tableau.

Exemple de données au format JSON :


 

Le module Python json


Pour formater des données Python en JSON et inversement, nous allons utiliser le
module Python standard json.

Lorsqu’on encode des données au format JSON, on dit également qu’on “sérialise” les
données. Ce terme fait référence à la transformation de données en une série d’octets.
Le processus inverse de décodage de données encodées au format JSON est également
appelé “désérialisation”.

La sérialisation des données Python


Pour sérialiser des données, c’est-dire pour convertir un objet Python en chaine JSON,
nous allons pouvoir utiliser l’une des méthodes dump() ou dumps() du module json.

La méthode dump() permet d’enregistrer les données JSON dans un fichier tandis


que dumps() (=“dump string”) renvoie simplement les données sous forme de chaine
JSON et nous permet de continuer à travailler avec elles.

Les objets Python vont être convertis selon la table d’équivalence suivante :

Python JSON

dict object

list, tuple array

str string

int, float number

True true

False false

None null

Prenons immédiatement un exemple :


Ici, on définit un dictionnaire Python pierre qui contient des données de types différents.

On ouvre ensuite un fichier “pierre.json” en écriture avec open() puis on écrit les données


sérialisées à l’intérieur grâce à dump(). On passe deux arguments à dump() : les données à
sérialisme et l’objet de type file (fichier) dans lequel elle doivent être écrites.

On utilise enfin la méthode dumps() pour convertir à nouveau les données en chaine


JSON et on les stocke dans une variable pour pouvoir s’en resservir dans elle reste du
script. On affiche affiche le contenu de la variable qui est bien une chaine JSON
constituée de différentes données formatées selon la table d’équivalence donnée ci-
dessus.
En réalité, vous devez savoir que les méthodes dump() et dumps() acceptent de nombreux
arguments qui vont nous permettre de personnaliser le comportement et notamment
d’arranger nos données comme des arguments de type “indentation”, “séparateur” ou
“classement des clefs” pour indenter les données, choisir nos séparateurs entre les
valeurs ou classer les données par clefs.

La désérialisation des données JSON


De la même façon, nous allons pouvoir utiliser l’une des méthodes load() et loads() pour
désérialiser des données JSON, c’st-à-dire pour convertir des données JSON en objet
Python.

La méthode load() permet de désérialiser des données JSON écrites dans un fichier


tandis que loads() permet de désérialiser des données directement sous forme due
chaine JSON.

La table de conversion des donnés va être la même que la précédente. En reprenant


notre exemple suivant, voici le résultat qu’on obtient :
Introduction à la gestion d’erreurs ou
d’exceptions en Python
En informatique, lors de l’exécution d’un programme, il y a toujours un risque d’erreur.
C’est la raison pour laquelle tout bon langage possède une gestion de base des erreurs
qui correspond concrètement en l’affichage d’un message d’erreur nous informant sur le
type d’erreur détectée et (souvent) en l’arrêt de l’exécution du programme après que
l’erreur ait été détectée.
Dans cette partie, nous allons apprendre à intercepter les erreurs renvoyées par Python
et à les gérer.

Les types d’erreurs et pourquoi gérer les


erreurs
On programmation, on peut rencontrer principalement deux types d’erreurs :

 Les erreurs de syntaxe dans le code faites par le développeur ;


 Les erreurs d’environnement qui ne sont pas du fait du développeur.
Par exemple, se servir d’une variable non déclarée dans un script, utiliser des opérateurs
avec des types de données qui ne les supportent pas ou oublier un guillemet ou un deux
points sont des erreurs de syntaxe faites par le développeur.

En revanche, tenter d’importer un module qui ne serait pas disponible à un temps t, ou


demander à un utilisateur d’envoyer un chiffre et recevoir une chaine par exemple va
produire une erreur qui n’est pas sûr au développeur.

Comme les erreurs de syntaxe sont des erreurs que nous avons faites, nous pouvons les
corriger directement et c’est ce qu’on s’efforcera à faire et modifiant nos scripts. Pour les
autres erreurs, en revanche, il va falloir mettre en place un système de gestion d’erreurs
qui indiquera au Python quoi faire si telle ou telle erreur est rencontrée.

Il est essentiel de fournir une gestion des erreurs d’environnement afin de garantir que
le script ne plante pas dans certaines situations et pour garantir l’intégrité et la sécurité
des données ainsi qu’une bonne expérience pour l’utilisateur qui n’a pas envie de voir
des messages d’erreur Python.

En Python, nous allons pouvoir intercepter certaines erreurs pour les prendre en charge
nous mêmes et pour décider si le script doit continuer de s’exécuter ou pas.

Les classes exception


En Python, les erreurs détectées durant l’exécution d’un script sont appelées des
exceptions car elles correspondent à un état “exceptionnel” du script.

Si vous essayez de déclencher des erreurs manuellement, vous pouvez constater que
Python analyse le type d’erreur et renvoie un message différent selon l’erreur détectée :

Ici, nous avons trois types d’exceptions différentes : une exception NameError, une
exception ZeroDivisionError et une exception TypeError. Comment fait Python pour
analyser les types d’erreurs et renvoyer des messages différents en fonction ?
En fait, vous devez savoir que Python possède de nombreuses classes d’exceptions
natives et que toute exception est une instance (un objet) créé à partir d’une classe
exception.

Afin de bien comprendre la hiérarchie des classes d’exceptions, vous pouvez retenir que
la classe d’exception de base pour les exceptions natives est BaseException. Toutes les
autres classes d’exception vont dériver de cette classe. Ensuite, nous avons également
quatre autres classes d’exception de base (qui dérivent de BaseException) :

 La classe Exception est la classe de base pour toutes les exceptions natives qui


n’entraînent pas une sortie du système et pour toutes les exceptions définies par
l’utilisateur (nous sommes l’utilisateur dans ce cas) ;
 La classe ArithmeticError est la classe de base pour les exceptions natives qui sont
levées pour diverses erreurs arithmétiques et notamment pour les
classes OverflowError, ZeroDivisionError et FloatingPointError ;
 La classe BufferError est la classe de base pour les exceptions levées lorsqu’une
opération liée à un tampon (“buffer”) ne peut pas être exécutée ;
 La classe LookupError est la classe de base pour les exceptions qui sont levées
lorsqu’une clé ou un index utilisé sur un tableau de correspondances ou une
séquence est invalide.
De nombreuses classes dérivent ensuite de ces classes de base. En fonction de l’erreur
rencontrée par l’analyseur Python, un objet exception appartenant à telle ou telle classe
exception va être crée et renvoyé. C’est cet objet là que nous allons pouvoir intercepter
et manipuler.

Pour la liste complète des classes d’exception, vous pouvez consulter la documentation.

Gérer les exceptions en Python avec


try, except, else et finally
Python nous fournit des structures permettant de gérer manuellement certaines
exceptions. Nous allons voir comment mettre en place ces structures dans cette leçon.
 

L’instruction try… except


Les clauses try et except fonctionnent ensemble. Elles permettent de tester (try) un code
qui peut potentiellement poser problème et de définir les actions à prendre si une
exception est effectivement rencontrée (except).

Imaginons par exemple un script qui demande à un utilisateur d’envoyer deux nombres
grâce à la fonction input() qui permet de recevoir des données d’utilisateurs externes.

Le but de notre script va être de calculer le quotient de ces deux nombres entiers. Ici, on
peut déjà anticiper des cas d’erreurs qui peuvent se présenter : l’utilisateur peut nous
envoyer autre chose qu’un nombre entier ou peut nous envoyer un dénominateur égal à
0, ce qui est interdit en mathématique.

On va vouloir gérer ces deux cas exceptionnels. Pour cela, on va pouvoir utiliser deux
blocs try et except comme cela :
Ici, on place le code à tester à l’intérieur du bloc try. Si aucune erreur n’est détectée par
Python lors de l’exécution du code, c’est-à-dire si aucun objet exception n’est créé, ce
qui se situe dans la clause except va être ignoré.

En revanche, si une exception intervient pendant l’exécution du code dans try, le reste du


code dans cette clause est ignoré et on rentre dans l’instruction except. Gérer les
exceptions comme cela permet notamment d’éviter l’arrêt de l’exécution du script dans
des cas où cela ne nous semble pas nécessaire.

Notre code ci-dessus est cependant loin d’être optimise car notre clause except est bien
trop large. Lorsqu’on gère les exceptions manuellement, on voudra toujours apporter la
gestion la plus fine possible pour éviter de capturer toutes les erreurs n’importe
comment.

Pour cela, nous allons préciser le type d’erreur qu’une instruction except doit intercepter.
Si on souhaite gérer plusieurs types d’exceptions, on pourra préciser autant
d’instructions except qu’on le souhaite à la suite d’un try.

Regardez plutôt le code ci-dessous :


Ce code est déjà beaucoup plus optimisé puisqu’il nous permet une gestion plus fine
des erreurs et ne va en l’occurence capturer que deux types d’exceptions : le cas où les
données entrées ne sont pas des entiers et le cas où le dénominateur est égal à 0.

Ce code demande cependant bien évidemment de connaitre les classes d’exception


Python, mais il suffit de consulter la documentation en cas de doute.

Notez que rien ne nous empêche de préciser un except sans classe à la fin si on souhaite
absolument donner des ordres dans le cas où Python capturerait tout autre type
d’exceptions que ceux correspondant aux clauses except précédentes.

La clause else
Nous allons également pouvoir ajouter une clause else en fin d’instruction try… except. Le
code contenu dans cette clause sera exécuté dans le cas où aucune exception n’a été
levée par la clause try.

Il est considéré comme une bonne pratique de placer le code “non problématique” dans
la clause else plutôt que dans la clause try.

On pourrait ainsi réécrire notre exemple précédent de la façon suivante :


 

La clause finally
La dernière clause à connaitre est la clause fin ally. Le code qu’elle contient sera exécuté
dans tous les cas, qu’une exception ait été levée par la clause try ou pas.

Cette clause va s’avérer très utile lorsqu’on voudra terminer certaines opérations (fermer
un fichier par exemple) quel que soit l’état du script.
 

Définir nos propres classes d’exception


Pour finir, vous devez savoir que Python nous laisse la possibilité de créer nos propres
classes d’exception.

Pour cela, nous allons toujours créer des classes à partir de la classe de base Exception.

Définir nos propres exceptions va s’avérer être une fonctionnalité très utile notamment
dans le cas où on souhaite distribuer un module Python et que certaines de nos
fonctions peuvent déclencher des exceptions non prises en charge par les classes
d’exception standard Python.

Travaille diriger en groupe

 
 

You might also like