PolyPython An
PolyPython An
Programmer en Python
Le résumé du résumé
© H. Garreta, 2014 1
Master Sciences Cognitives
1 Mise en place 4
1.1 Obtenir Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Utiliser Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Expressions 6
2.1 Constantes numériques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Chaı̂nes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Opérateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Structures de contrôle 10
3.1 Instruction conditionnelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2 Boucle tant que . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Boucle pour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 Break et else dans les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4 Structures de données 14
4.1 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.3 Ensembles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.4 Dictionnaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.5 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5 Fonctions 19
5.1 Notions et syntaxe de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.2 Variables locales et globales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.3 Plus sur les paramètres formels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.4 Fonctions récursives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.5 Forme lambda et list comprehension . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.6 Chaı̂ne de documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6 Entrées-sorties 25
6.1 Acquisition de données au clavier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.2 Affichage de données mises en forme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.3 Fonctions pour les fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2 © H. Garreta, 2014
TABLE DES MATIÈRES TABLE DES MATIÈRES
7 Modules 31
8 Classes 32
8.1 Constructeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
8.2 Conversion sous forme d’une chaı̂ne de caractères . . . . . . . . . . . . . . . . . . . . . 33
8.3 Héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
9 Exceptions 35
10 Annexes 37
10.1 Opérations sur les séquences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
10.2 Les scripts donnés en exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
© H. Garreta, 2014 3
Master Sciences Cognitives
1 Mise en place
Le site officiel du langage Python est : http://www.python.org/. On peut y télécharger librement la dernière
version de Python 3 1 (l’interpréteur et les bibliothèques) pour la plupart des systèmes d’exploitation. La docu-
mentation officielle, très copieuse, peut également être parcourue ou téléchargée à partir de ce site. Le langage
Python peut être étendu par de nombreuses bibliothèques (extensions logicielles) qui ne sont pas inclues dans
l’installeur.
Pour programmer en python, on peut utiliser un éditeur de texte avec coloration syntaxique (par exemple
Notepad++ https://notepad-plus-plus.org/, Sublime https://www.sublimetext.com/, ou Visual Studio
https://code.visualstudio.com/...) ou un environnement de développement intégré, comme Pycharm, Spy-
der, etc. qui offrent une grande productivité mais sont réservés aux utilisateurs expérimentés. Dans ce cours,
nous opterons pour la première solution.
Que ce soit sur Windows, Mac ou Linux, la mise en place de Python ne pose aucun problème. Après une
installation réussie, vous avez surtout deux manières d’utiliser l’interpréteur :
1°) Interactivement, en saisissant des commandes Python l’une après l’autre. Par exemple, voici une session
interactive dans une console Linux pour exécuter certaines instructions (“bash_$” est l’invite de mon système
Linux, “>>>” celle de l’interpréteur Python ; les textes tapés par l’utilisateur ont été reproduits en caractères
penchés) :
bash_$ python
Python 3.7.4 (default, Jul 16 2019, 07:12:58)
[GCC 9.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 100 / 3
33.333333333333336
>>> 1 + 3
4
>>> 100 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> quit()
bash_$
Notez que sur Windows, le programme IDLE, qui s’installe en même temps que Python, ouvre une console
particulièrement bien adaptée à la pratique de Python.
2°) En exécutant un programme (on dit volontiers un script) préalablement saisi. Par exemple, si on a écrit un
script, dans un fichier nommé factorielle.py, pour évaluer la factorielle n! = n × (n − 1) × · · · × 3 × 2 × 1
d’un nombre n lu au clavier, voici comment en obtenir l’exécution :
1. Il existe deux version incompatibles de python, la version 2 et la version 3. Certains systèmes d’exploitation sont
livrés avec python 2 préinstallé mais pas python 3. Python 2 est en fin de vie et conservé uniquement pour faire fonctionner
de vieux logiciels. Il convient d’installer la version 3 pour ce cours.
4 © H. Garreta, 2014
TABLE DES MATIÈRES 1. MISE EN PLACE
Si vous lisez déjà le Python, le texte du fichier factorielle.py est visible à la section 5.4, page 23.
© H. Garreta, 2014 5
Master Sciences Cognitives
2 Expressions
Une constante littérale est l’expression écrite d’une valeur connue ; exemples : 12, -5, 3.5, 0, etc.
La donnée représentée par une constante a toujours un type qui détermine ses propriétés formelles (comme :
quelles opérations la donnée peut-elle subir ?) et matérielles (comme : combien d’octets la donnée occupe-t-elle
dans la mémoire de l’ordinateur ?). La manière la plus simple et la plus fiable de connaı̂tre le type d’une expres-
sion consiste à poser la question à Python.
>>> type(0)
<class 'int'>
>>> type(-5)
<class 'int'>
>>> type(2000000000)
<class 'int'>
>>> type(-5.0)
<class 'float'>
>>> type(602.21417e+021)
<class 'float'>
>>>
En ignorant la présentation <class 'un type'>, délibérément biscornue, le dialogue précédent nous apprend, ou
du moins nous suggère, que
— sans surprise, des constantes comme 0, -5 ou 2000000000 représentent des nombres entiers (type int),
— dès qu’une constante numérique comporte un point, qui joue le rôle de virgule décimale, Python com-
prend qu’il s’agit d’un nombre décimal, on dit plutôt flottant, et le représente en machine comme tel
(type float),
— lorsque les nombres décimaux sont très grands ou très petits on peut employer la « notation scientifique »
bien connue ; par exemple, la constante 602.21417e+021 représente le nombre 6, 0221417×1023 ou encore
602214170000000000000000,
— le caractère flottant d’un nombre est « contagieux » : si une opération arithmétique a un opérande
entier et un opérande flottant, alors pour effectuer l’opération l’entier est d’abord converti en flottant
et l’opération est faite selon les règles des nombres flottants ; exemple : le résultat de la multiplication
1.0 * 5 est le nombre flottant 5.0.
2.2 Variables
Un identificateur est une suite de lettres et de chiffres qui commence par une lettre et n’est pas un mot réservé
(comme if, else, def, return, etc.). Le caractère _ est considéré comme une lettre.
Exemples : prix, x, x2, nombre_de_pieces, vitesseDuVent, etc.
Majuscules et minuscules n’y sont pas équivalentes : prix, PRIX et Prix sont trois identificateurs distincts.
Une variable est constituée par l’association d’un identificateur à une valeur. Cette association est créée lors
d’une affectation, qui prend la forme
variable = valeur
A la suite d’une telle affectation, chaque apparition de la variable ailleurs que dans la partie gauche d’une autre
affectation représente la valeur en question... jusqu’à ce qu’une nouvelle affectation associe une autre valeur à la
variable. On confond parfois le nom de la variable (c.-à-d. l’identificateur) et la variable elle-même (l’association
du nom à une valeur) ; c’est sans gravité.
6 © H. Garreta, 2014
TABLE DES MATIÈRES 2. EXPRESSIONS
Si un identificateur n’a pas été affecté (en toute rigueur il n’est donc pas un nom de variable) son emploi ailleurs
qu’au membre gauche d’une affectation est illégale et provoque une erreur. Session Python de démonstration :
>>> nombre
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'nombre' is not defined
>>> nombre = 10
>>> nombre
10
>>> nombre = 20.5
>>> nombre
20.5
>>>
Comme on le voit sur cet exemple, en Python :
1. Les variables n’ont pas besoin d’être déclarées (c’est-à-dire préalablement annoncées), la première affec-
tation leur tient lieu de déclaration.
2. Les variables ne sont pas liées à un type (mais les valeurs auxquelles elles sont associées le sont for-
cément) : la même variable nombre a été associée à des valeurs de types différents (un int, puis un
float).
L’affichage basique d’une telle chaı̂ne est décevant (voir ci-dessus) mais montre bien que les fins de ligne,
représentés par le signe \n, ont été conservés. L’affichage à l’aide de la fonction print est plus esthétique :
>>> print(s)
Ceci est une cha^
ıne
comportant plusieurs lignes. Notez que
les blancs en t^
ete de ligne
sont conservés
>>>
Concaténation. L’opérateur + appliqué à deux chaı̂nes de caractères produit une nouvelle chaı̂ne qui est la
concaténation (c’est-à-dire la mise bout-à-bout) des deux premières :
© H. Garreta, 2014 7
2. EXPRESSIONS TABLE DES MATIÈRES
Accès à un caractère individuel. On accède aux caractères d’une chaı̂ne en considérant celle-ci comme
une séquence indexée par les entiers : le premier caractère a l’indice 0, le second l’indice 1, le dernier l’indice
n − 1, n étant le nombre de caractères.
Exemples :
>>> s = ’Bonjour’
>>> s[0]
'B'
>>> s[6]
'r'
>>> s[-1]
'r'
>>>
Le nombre de caractères d’une chaı̂ne s est donné par l’expression len(s). Pour accéder aux caractères à la
fin d’une chaı̂ne il est commode d’employer des indices négatifs : si i est positif, s[-i ] est la même chose que
s[len(s) - i ].
Tranches. On peut désigner des tranches dans les chaı̂nes ; la notation est chaı̂ne[début:fin] où début est
l’indice du premier caractère dans la tranche et fin celui du premier caractère en dehors de la tranche. L’un
et l’autre de ces deux indices peuvent être omis, et même les deux. De plus, ce mécanisme est tolérant envers
les indices trop grands, trop petits ou mal placés :
>>> s = ’Bonjour’
>>> s[3 :5]
'jo'
>>> s[3 :]
'jour'
>>> s[ :5]
'Bonjo'
>>> s[ :]
'Bonjour'
>>> s[6 :3]
''
>>> s[-100 :5]
'Bonjo'
>>> s[3 :100]
'jour'
>>>
Les chaı̂nes de caractères sont immuables : une fois créées il ne peut rien leur arriver. Pour modifier des caractères
d’une chaı̂ne on doit construire une nouvelle chaı̂ne qui, si cela est utile, peut remplacer la précédente. Par
exemple, proposons-nous de changer en ’J’ le ’j’ (d’indice 3) de la chaı̂ne précédente :
>>> s
'Bonjour'
>>> s[3] = ’J’
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> s = s[ :3] + ’J’ + s[4 :]
>>> s
'BonJour'
>>>
2.4 Opérateurs
Opérateurs arithmétiques.
8 © H. Garreta, 2014
TABLE DES MATIÈRES 2. EXPRESSIONS
+, -, * : addition, soustraction, multiplication. Ces opérateurs obéissent à la règle dite « du plus fort » : si
un des opérandes est flottant, l’autre opérande est converti si nécessaire en flottant et l’opération et le
résultat sont flottants. Si, au contraire, les deux opérandes sont entiers, l’opération et le résultat sont
entiers.
/ : division. La division renvoie toujours un résultat de type float, même si les opérandes sont entiers et
que le résultat l’est aussi.
>>> type(4/2)
<class 'float'>
Priorité des opérateurs. Les opérateurs multiplicatifs *, / et % ont une priorité supérieure à celle des
opérateurs additifs + et -. Cela signifie, par exemple, que l’expression a ∗ b + c exprime une addition (dont le
premier terme est le produit a ∗ b). L’emploi de parenthèses permet de contourner la priorité des opérateurs. Par
exemple, l’expression a ∗ (b + c) représente bien une multiplication (dont le second facteur est l’addition b + c).
Heureusement, ce qu’il faut savoir en programmation à propos de la priorité des opérateurs coı̈ncide avec la
pratique constante en algèbre (rappelez-vous « une expression est une somme de termes, un terme est un produit
de facteurs ») ; c’est pourquoi nous ne développerons pas davantage cette question ici.
Opérateurs de comparaison.
La règle du plus fort vaut aussi pour les comparaisons : les deux opérandes sont amenés à un type commun
avant l’évaluation de la comparaison.
Conformément à l’habitude répandue, la priorité des opérateurs de comparaison est inférieure à celle des opé-
rateurs arithmétiques. Ainsi, l’expression a == b + c signifie bien a == (b + c).
Booléens et opérateurs booléens. Le résultat d’une comparaison comme a == b est de type booléen
(bool) ; ce type ne possède que deux valeurs, False (faux) et True (vrai).
A certains endroits, comme les conditions des instructions if ou while, le langage prescrit la présence d’ex-
pressions dont le résultat doit être de type booléen. Par une tolérance ancienne, maintenant découragée, on
peut mettre à la place une expression quelconque ; elle fonctionnera comme un booléen à l’aide de la convention
suivante :
— seront tenus pour faux : False, None, le zéro de n’importe quel type numérique (0, 0.0), la chaı̂ne de
caractères vide et toute structure de données vide (liste, ensemble, table associative, etc.),
— toute autre valeur sera tenue pour vraie.
Les connecteurs logiques sont
— not (négation) : not a est vraie si et seulement si a est fausse,
— and (conjonction) : a and b est vraie si et seulement si a et b sont toutes deux vraies,
— or (disjonction) : a or b est vraie si et seulement si au moins une deux expressions a, b est vraie.
Notez que les opérateurs and et or sont « optimisés » de la manière suivante : le premier opérande est évalué
d’abord ; si sa valeur permet de prédire le résultat de l’opération (c.-à-d. si a est faux dans a and b ou vrai dans
a or b) alors le second opérande n’est même pas évalué. Cela permet d’écrire des expressions dont le premier
terme « protège » le second, comme (rappelez-vous que diviser par zéro est une erreur qui plante le programme) :
2. Étant donnés deux nombres entiers a et b, avec b > 0, faire la division euclidienne de a par b consiste à déterminer
deux nombres entiers q et r vérifiant a = b × q + r et 0 ≤ r < b. On dit alors que q est le quotient et r le reste de la
division de a par b. En Python on a donc a//b = q et a%b = r.
© H. Garreta, 2014 9
Master Sciences Cognitives
3 Structures de contrôle
Python et l’indentation. L’indentation (c’est-à-dire la marge blanche laissée à gauche de chaque ligne) joue
un rôle syntaxique et permet d’économiser les accolades {...} et les begin...end d’autres langages. En contrepartie,
elle obéit à des règles strictes :
1. Une séquence d’instructions (instructions consécutives, sans subordination entre elles) est faite d’ins-
tructions écrites avec la même indentation.
2. Dans une structure de contrôle (instruction if, for, def) une séquence d’instructions subordonnées doit
avoir une indentation supérieure à celle de la première ligne de la structure de contrôle. Toute ligne
écrite avec la même indentation que cette première ligne marque la fin de la séquence subordonnée.
vrai faux
condition1
vrai faux
instruction1 condition2
...
instructionp
instructionp+1 instructionq+1
... ...
instructionq instructionr
Le groupe de lignes de « elif condition 2 : » à « instruction q » peut apparaı̂tre un nombre quelconque de fois
ou être absent. Le groupe de lignes qui va de « else : » à « instruction r » peut être absent.
• Exemple de script 1. Résolution d’une équation du second degré : étant donnés trois nombres a, b et c,
avec a 6= 0, trouver les valeurs de x vérifiant ax2 + bx + c = 0.√Algorithme bien√ connu : examiner le signe de
∆ = b2 − 4ac. Si ∆ > 0 il y a deux solutions réelles x1 = −b+ 2a
∆
et x2 = −b−2a
∆
. Si ∆ = 0 il y a une seule
−b
solution, x = 2a . Si ∆ < 0 il n’y a pas de solution (ou, du moins, pas de solution réelle).
10 © H. Garreta, 2014
TABLE DES MATIÈRES 3. STRUCTURES DE CONTRÔLE
Programme :
a = float(input("a : "))
b = float(input("b : "))
c = float(input("c : "))
delta = b * b - 4 * a * c
if delta > 0:
x1 = (-b + sqrt(delta)) / (2 * a)
x2 = (-b - sqrt(delta)) / (2 * a)
print ('deux solutions:', x1, x2)
elif delta == 0:
x = -b / (2 * a)
print ('une solution:', x)
else:
print ('pas de solution reelle')
while condition 1 :
instruction 1
...
instruction p
else :
instruction p+1
...
instruction q
vrai faux
condition1
instruction1 instructionp+1
... ...
instructionp instructionq
La partie qui va de « else : » à « instruction q » peut être absente. Pratiquement, elle n’a d’intérêt que si une
instruction break est présente dans la boucle.
• Exemple de script 2. Étant donné un nombre positif a, trouver le plus petit entier k vérifiant a ≤ 2k .
Algorithme naı̈f (il y a plus efficient) : construire successivement les termes de la suite 2k (20 = 1, 21 = 2,
22 = 4, 23 = 8, 24 = 16...) jusqu’à ce qu’ils égalent ou dépassent la valeur de a. Programme :
a = input("a : ")
k = 0
p = 1 # on veille à avoir constamment p = 2**k
© H. Garreta, 2014 11
3. STRUCTURES DE CONTRÔLE TABLE DES MATIÈRES
while p < a:
p = p * 2
k = k + 1
print ('k:', k, ' 2^k:', p)
Syntaxe :
La partie qui va de « else : » à « instruction q » peut être absente. Pratiquement, elle n’a d’intérêt que si une
instruction break est présente dans la boucle.
Fonctionnement : si la séquence indiquée est composée des éléments valeur 1 , valeur 2 , ... valeur k alors l’exécution
de la structure précédente revient à l’exécution de la séquence :
variable = valeur 1
instruction 1
...
instruction p
variable = valeur 2
instruction 1
...
instruction p
...
variable = valeur k
instruction 1
...
instruction p
instruction p+1
...
instruction q
Ainsi, la boucle for de Python prend toujours la forme du parcours d’une séquence préexistante. Pour obtenir
la forme plus classique « pour i valant successivement a, a + p, a + 2 × p, ... b » (dont un cas particulier archi-
fréquent est « pour i valant successivement 0, 1, ... k ») on emploie la fonction range qui construit une séquence
sur demande :
Pour cerner la fonction range on peut s’en faire montrer le fonctionnement par Python. Session :
12 © H. Garreta, 2014
TABLE DES MATIÈRES 3. STRUCTURES DE CONTRÔLE
L’instruction break placée à l’intérieur d’une boucle while ou for produit l’abandon immédiat de la boucle et
la continuation de l’exécution par la première instruction qui se trouve après la boucle. La clause else, si elle
est présente, n’est alors pas exécutée.
• Exemple de script 3. Chercher l’indice de la première occurrence d’un caractère c dans une chaı̂ne s 3 ;
renvoyer la valeur de cet indice ou -1 si c n’est pas présent dans s :
Attention, piège ! Notez que else est indenté comme for. L’aligner avec if aurait complètement changé le
sens de ce bout de code et l’aurait rendu faux.
3. Cet exemple est important, car il est l’archétype du problème recherche linéaire d’une valeur dans une séquence.
Cependant, il faut savoir que s’agissant de la recherche d’un caractère dans une chaı̂ne il n’est pas nécessaire d’écrire un
programme, la fonction s.find(c) de la bibliothèque Python répond parfaitement à la question.
© H. Garreta, 2014 13
Master Sciences Cognitives
4 Structures de données
4.1 Tuples
Un tuple est une séquence immuable : on ne peut pas modifier ses éléments ni lui en ajouter ou lui en enlever.
En contrepartie de cette rigidité les tuples sont très compacts (i.e. ils occupent peu de mémoire) et l’accès à
leurs éléments est très rapide.
On crée un tuple en écrivant ses éléments, séparés par des virgules et encadrés par des parenthèses. Si cela ne
crée aucune ambiguı̈té, les parenthèses peuvent être omises. Un tuple constitué d’un seul élément a doit être
écrit « a, » ou « (a,) ». Le tuple sans éléments se note « () ».
Dans les exemples suivants, la valeur de la variable t est un tuple de cinq éléments :
Comme on le voit, un élément d’un tuple peut être un tuple à son tour. C’est tellement facile et pratique qu’on
écrit des tuples sans s’en rendre compte : l’expression « t, type(t), len(t) » est elle-même un tuple de trois
éléments.
Un tuple de variables peut figurer comme membre gauche d’une affectation, il faut alors que le membre droit
soit un tuple de même taille :
>>> point = 3, 4
>>> point
(3, 4)
>>> x, y = point
>>> x
3
>>> y
4
>>>
4.2 Listes
Une liste est une séquence modifiable : on peut changer ses éléments, lui en ajouter et lui en enlever. Cela rend
les listes un peu moins compactes et efficaces que les tuples, mais considérablement plus utiles pour représenter
des structures de données qui évoluent au cours du temps.
On construit une liste en écrivant ses éléments, séparés par des virgules, encadrés par les crochets. La liste vide
se note [ ]. Voici quelques opérations fondamentales sur les listes (voir aussi 10.1) :
14 © H. Garreta, 2014
TABLE DES MATIÈRES 4. STRUCTURES DE DONNÉES
N.B. Il y a donc deux manière de commander l’opération « ajouter un élément à la fin d’une liste ». On prendra
garde à cette différence entre elles :
liste + [ élément ] ne modifie pas liste, mais renvoie une nouvelle liste comme résultat,
liste.append(élément) modifie liste et ne renvoie pas de résultat.
• Exemple de script 4. Calcul de la liste des nombres premiers inférieurs ou égaux à une certaine borne.
Algorithme : passer en revue chaque nombre impair (les nombres pairs ne sont pas premiers), depuis 3 jusqu’à
la borne donnée, en recherchant s’il est divisible par un des nombres premiers déjà trouvés, ce qui signifierait
qu’il n’est pas premier. Programme :
4.3 Ensembles
Les ensembles sont des structures de données avec les caractéristiques suivantes :
— il n’y a pas d’accès indexé aux éléments, ni d’ordre entre ces derniers,
— il n’y a pas de répétition des éléments : un élément appartient ou non à un ensemble, mais cela n’a pas
de sens de se demander s’il s’y trouve plusieurs fois,
— en contrepartie, le test d’appartenance est optimisé : le nécessaire est fait pour que le test élément ∈
ensemble ? (en Python : élément in ensemble) puisse être évalué de manière extrêmement efficace.
set( séquence )
où séquence est une donnée parcourable (liste, tuple, chaı̂ne de caractères, etc.). Exemple :
>>> s = set("abracadabra")
>>> s
{'a', 'r', 'b', 'c', 'd'}
>>>
© H. Garreta, 2014 15
4. STRUCTURES DE DONNÉES TABLE DES MATIÈRES
Notez que les opérations a.issubset(b), a.union(b), a.intersection(b) et a.difference(b) peuvent aussi
se noter, respectivement, a <= b, a | b, a & b et a - b.
• Exemple de script 5. Déterminer les caractères qui apparaissent exactement une fois dans un texte donné.
Algorithme : déterminer l’ensemble des caractères qui apparaissent au moins une fois et l’ensemble de ceux qui
apparaissent plus d’une fois ; la différence entre ces deux ensembles est la réponse à la question.
print (auMoinsUneFois.difference(auMoinsDeuxFois))
4.4 Dictionnaires
Un dictionnaire, ou table associative, est une collection de couples (clé, valeur ) telle que
— il n’y a pas deux couples ayant la même clé,
— la structure est implémentée de manière que la recherche d’une valeur à partir de la clé correspondante
soit extrêmement efficace.
Les clés ne doivent pas être des structures modifiables mais, à part cela, elles peuvent être de n’importe quel
type ; les valeurs sont quelconques. On construit explicitement un dictionnaire par une expression de la forme
dict[clé] = valeur ajoute au dictionnaire dict une paire (clé, valeur ) ou, si une telle paire
existait déjà, modifie sa partie valeur,
dict[clé] renvoie la valeur correspondant à la clé donnée ; une erreur est déclenchée
si une telle clé n’existe pas dans le dictionnaire,
dict.get(clé [,valsinon]) renvoie la valeur correspondant à la clé donnée ; si une telle clé est absente,
renvoie valsinon ou (si valsinon est omise) None,
clé in(d ict) vrai si et seulement si la clé indiquée existe dans le dictionnaire dict,
del dict[clé] supprime du dictionnaire dict la paire (clé, valeur ),
list(dict.keys()) renvoie une copie de la liste des clés du dictionnaire dict,
list(dict.values()) renvoie une copie de la liste des valeurs du dictionnaire dict,
list(dict.items()) renvoie une copie de la liste des associations constituant le dictionnaire dict.
• Exemple de script 6. Compter le nombre d’apparitions de chaque caractère d’un texte donné. Algorithme :
construire un dictionnaire dont les clés sont les caractères du texte et les valeurs le nombre d’occurrences de
chacun. Programme :
16 © H. Garreta, 2014
TABLE DES MATIÈRES 4. STRUCTURES DE DONNÉES
dico = { }
for car in texte:
if dico.has_key(car):
dico[car] = dico[car] + 1
else:
dico[car] = 1
4.5 Tableaux
Les tableaux les plus basiques 4 , comme ceux des langages C ou Java, existent en Python mais ne font pas partie
du cœur du langage. Définis dans le module array de la bibliothèque standard, pour pourvoir les utiliser dans
un programme on doit écrire au début de celui-ci la directive
Il s’agit de tableaux simples et homogènes. Cela veut dire que leurs éléments doivent avoir un type commun,
et que ce doit être un type primitif de la machine sous-jacente (ou plutôt du langage C dans lequel la machine
Python est écrite).
Lors de la création d’un tableau on doit indiquer le type de ses éléments ; cela se fait par une lettre : ’i’ pour
un tableau d’entiers, ’f’ pour un tableau de flottants, etc. Exemple, création d’un tableau d’entiers (il n’est
pas nécessaire à ce niveau de donner la taille – nombre maximum d’éléments – du tableau) :
tableau = array(’i’)
Voici les principales opérations qu’un tel tableau pourra subir ensuite :
• Exemple de script 7. On reprend le problème de l’exemple de la section 4.4, compter le nombre d’occurrences
de chaque caractère d’un texte, qu’on résout ici en utilisant un tableau de 256 compteurs, chacun destiné à
compter le nombre d’apparitions d’un caractère (on suppose que le texte est écrit avec les 256 caractères usuels
« iso-8859-1 »). Programme :
4. Quel que soit le langage de programmation utilisé, un array (en français on dit tableau) est un arrangement
d’éléments contigus et de même type. C’est une structure compacte (l’encombrement du tableau est celui de ses éléments,
aucune mémoire additionnelle n’est requise) et très efficace (l’accès à un élément à partir de son indice se fait en un
temps constant).
© H. Garreta, 2014 17
4. STRUCTURES DE DONNÉES TABLE DES MATIÈRES
compteurs = array('i')
compteurs.extend( [ 0 ] * 256 )
for c in texte:
compteurs[ord(c)] = compteurs[ord(c)] + 1
for i in range(256):
if compteurs[i] != 0:
print (chr(i), ':', compteurs[i], 'occurrence(s)')
On remarquera dans le programme précédent comment le tableau est initialisé avec une liste de 256 zéros
(concaténation de 256 exemplaires de la liste [ 0 ]).
18 © H. Garreta, 2014
Master Sciences Cognitives
5 Fonctions
Définition de fonction :
La ligne « def nomFonction(argument 1 , argument 2 , ... argument k ) » est appelée l’en-tête de la fonction ; la
séquence « instruction 1 , instruction 2 , ... instruction p » le corps de cette dernière. La fin du corps, et donc de la
définition de la fonction, est indiquée par l’apparition de lignes ayant la même indentation que l’en-tête.
Appel de fonction. L’effet d’une définition de fonction n’est pas d’exécuter les instructions qui en composent
le corps, mais uniquement de mémoriser ces instructions en vue d’une (hypothétique) exécution ultérieure,
provoquée par une expression, appelée appel de la fonction, qui prend la forme
nomFonction(expression 1 , expression 2 , ... expression k )
Les expressions expression 1 , expression 2 , ... expression k sont appelées les arguments effectifs de l’appel. Leurs
valeurs sont affectées à argument 1 , argument 2 , ... argument k , les arguments formels de la fonction, juste avant
l’exécution de son corps, comme si cette exécution commençait par une série d’affectations :
argument 1 = expression 1
argument 2 = expression 2
...
argument k = expression k
Très souvent, le corps d’une fonction contient une ou plusieurs instructions de la forme
return expression
dans ce cas, l’appel de la fonction, à l’endroit où il est écrit, représente cette valeur renvoyée ; cet appel prend
alors plutôt la forme
resultat = nomFonction(expression 1 , expression 2 , ... expression k )
La figure 3 montre l’ordre chronologique d’exécution des instructions d’un programme comportant la définition
et l’appel d’une fonction.
• Exemple de script 8. Voici une fonction qui calcule la moyenne et l’écart-type des éléments d’une liste de
nombres. Programme :
def moyenneEcartType(listeVal):
nombre = 0
sommeValeurs = 0.0
sommeCarres = 0.0
for x in listeVal:
nombre += 1
sommeValeurs += x
sommeCarres += x * x
moyenne = sommeValeurs / nombre
ecartt = sqrt(sommeCarres / nombre - moyenne * moyenne)
return (moyenne, ecartt)
© H. Garreta, 2014 19
5. FONCTIONS TABLE DES MATIÈRES
2 5
valeurs = [ 1, 9, 4, 6, 8, 2, 5, 3, 7 ]
resultat = moyenneEcartType(valeurs)
print (resultat)
uneValeur = 64
uneListe = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
p = position(uneValeur, uneListe)
if p >= 0:
print ("la valeur est a la position", p)
else:
print ("la valeur n'est pas presente")
20 © H. Garreta, 2014
TABLE DES MATIÈRES 5. FONCTIONS
global nomDeVariable
Par exemple, imaginons une fonction dont on voudrait connaı̂tre le nombre de fois qu’elle est appelée pendant
le déroulement d’un programme. Voici comment :
def uneFonction():
global nbrAppels # sans cela nbrAppels serait une (nouvelle) variable locale
nbrAppels = nbrAppels + 1
#le reste de la fonction
...
#et, vers la fin du script, on ajoutera
print (nbrAppels, 'appels de uneFonction')
Paramètres avec valeur par défaut. Lors de la définition d’une fonction il est possible de spécifier des
valeurs par défaut pour un ou plusieurs des arguments formels. Cela permet d’appeler la fonction avec moins
d’arguments effectifs que d’arguments formels, les valeurs par défaut remplaçant les arguments manquants.
• Exemple de script 10. Le script suivant pose une question fermée (dont la réponse est oui ou non) et permet
de recommencer un certain nombre de fois, tant que la réponse n’est pas dans une liste de bonnes réponses :
def demanderAccord(question, essais = 1000, alerte = "oui ou non, s'il vous plait!"):
while True:
reponse = input(question).lower().strip()
if reponse in ('o', 'oui'):
return True
if reponse in ('n', 'non'):
return False
essais -= 1
if essais < 0:
raise IOError, "l'utilisateur semble incapable de répondre"
print (alerte)
Paramètres à mot clé. Les paramètres effectifs d’un appel de fonction peuvent être donnés dans un ordre
différent de celui des arguments formels : il suffit pour cela d’écrire les arguments déplacés sous la forme de
couples nomArgumentFormel = expression.
© H. Garreta, 2014 21
5. FONCTIONS TABLE DES MATIÈRES
Par exemple, voici une fonction (censée afficher un texte dans une fenêtre graphique) avec de nombreux argu-
ments ayant des valeurs par défaut :
afficher('Salut')
...
afficher('Salut', police = "Times", avantPlan = 0xFF0000)
...
afficher(x = 50, y = 200, texte = 'Salut', style = "italic")
Arguments en nombre variable. Si une fonction comporte un argument formel précédé d’une étoile * alors
lors d’un appel on pourra mettre à cet endroit un nombre quelconque d’arguments effectifs ; le paramètre formel
sera affecté par le tuple formé par ces arguments.
Par exemple, la fonction (purement démonstrative) suivante :
peut être appelée avec un nombre quelconque de paramètres effectifs, à la condition qu’il y en ait au moins
deux. Les deux premiers seront affectés à a et b respectivement, tandis que c sera affecté par le tuple formée de
tous les autres arguments. Essais : les trois appels suivants
affichent respectivement
def applique_liste(f,l):
s = []
for e in l:
s.append(f(e))
return s
La fonction applique_liste construit et renvoie une nouvelle liste (s) dont les éléments sont calculés par
application de la fonction f aux éléments de l. Voici un exemple d’appel de la fonction applique_liste, qui
consiste a appeler la fonction carre sur les élements de la liste [1,2,3].
• Exemple de script 11
def carre(x):
return x * x
applique_liste(carre, [1,2,3])
22 © H. Garreta, 2014
TABLE DES MATIÈRES 5. FONCTIONS
Une fonction est dite récursive lorsque son corps contient un ou plusieurs appels d’elle-même. Par exemple, la
factorielle d’un nombre n se définit « itérativement » par n! = n × (n − 1) × (n − 2) × · · · × 2 × 1. Il est évident
si n ≤ 1 alors 1
qu’une définition récursive de la même quantité est : n! = , ce qui donne le code suivant :
sinon n × (n − 1)!
• Exemple de script 12. Calcul récursif de n!.
def fact(n):
if n <= 1:
return 1
else:
return n * fact(n - 1)
# essai:
n = int(input("nombre ? "))
print (n, '! =', fact(n))
Les formes lambda sont généralement utilisées lorsqu’on a besoin de définir une fonction dont on va avoir besoin
une seule fois, comme arguments d’une fonction d’ordre supérieur (voir ci-dessus), par exemple. L’exemple de
la section 5.3 peut être réecrit à l’aide d’une forme lambda de la manière suivante :
print(applique_liste(lambda x : x * x, [1,2,3]))
Cette expression construit la liste formée par les résultats des évaluations de expression obtenus en donnant
au tuple de variables (var 1 , var 2 , ... var k ) successivement les valeurs de la séquence indiquée. La partie « for
var 1 , var 2 , ... var k in séquence » peut se répéter. Exemples pour comprendre :
>>> t = (1, 2, 3, 4, 5)
>>> [x for x in t]
[1, 2, 3, 4, 5]
>>> [x * x for x in t]
[1, 4, 9, 16, 25]
>>> [ x * y for x in t for y in t]
[1, 2, 3, 4, 5, 2, 4, 6, 8, 10, 3, 6, 9, 12, 15, 4, 8, 12, 16, 20, 5, 10, 15, 20, 25]
© H. Garreta, 2014 23
5. FONCTIONS TABLE DES MATIÈRES
La chaı̂ne de documentation d’une fonction est une chaı̂ne de caractères écrite entre l’en-tête et le corps. Sa
présence n’est pas une obligation mais est fortement recommandée du point de vue méthodologique, car elle
permet d’expliciter avec concision et précision l’algorithme implémenté par la fonction, ses arguments, son
résultat, les contraintes que doivent satisfaire les uns et les autres, etc.
Outre d’éventuels lecteurs (humains) de votre programme, la chaı̂ne de documentation s’adresse à l’interpréteur
Python, qui est capable de l’exploiter, notamment lors de la construction automatique de la documentation.
Pour cette raison, la structure de cette chaı̂ne est imposée ; elle se compose
— d’une première ligne, commençant par une majuscule et finissant par un point,
— suivie par une ligne blanche,
— suivie par un texte de plusieurs lignes dans lequel on a un peu plus de liberté.
• Exemple de script 13. Voici une nouvelle rédaction de l’exemple de la section 5.1 :
def moyenneEcartType(listeVal):
"""Moyenne et écart-type d'une liste de nombres.
listeVal doit ^
etre une liste de nombres non vide
renvoie les valeurs de la moyenne et l'écart-type
sous forme d'un tuple de deux nombres flottants
"""
nombre = 0
sommeValeurs = 0.0
sommeCarres = 0.0
for x in listeVal:
nombre += 1
sommeValeurs += x
sommeCarres += x * x
moyenne = sommeValeurs / nombre
ecartt = sqrt(sommeCarres / nombre - moyenne * moyenne)
return (moyenne, ecartt)
24 © H. Garreta, 2014
Master Sciences Cognitives
6 Entrées-sorties
input(invite)
Cette fonction affiche l’invite indiquée puis engrange tout ce que l’utilisateur tape au clavier jusqu’à la frappe
d’une fin de ligne (la touche Entrée). La fonction renvoie les caractères ainsi acquis sous forme d’une chaı̂ne de
caractères. Essai :
Cette fonction est souvent employée pour acquérir des données qui ne sont pas des chaı̂nes (des nombres, etc.).
Il faut alors la composer avec une fonction de conversion qui, en principe, a le même nom que le type visé (int,
float, etc.). Exemple :
Une différence notable entre l’affichage automatique du résultat d’une évaluation et l’affichage que produit la
fonction print : le premier affiche des données réinjectables, c’est-à-dire possédant la syntaxe qu’elles doivent
avoir lorsqu’elles sont écrites dans les scripts, tandis que le second écrit des données nettoyées, plus lisibles par
un humain. Démonstration :
© H. Garreta, 2014 25
6. ENTRÉES-SORTIES TABLE DES MATIÈRES
Les expressions sont évaluées et les valeurs obtenues sont affichées, chacune séparée de la suivante par une
espace.
Le end='' est facultatif : s’il est présent, la dernière donnée ne sera pas suivie d’une fin de ligne ; s’il est absent,
la dernière donnée sera suivie d’une fin de ligne de sorte que les éventuels affichages ultérieurs se feront sur les
lignes en-dessous.
Pour une mise en forme plus savante il faut employer cette fonction sous la forme
où chaı̂ne de caractères est le résultat de la mise en forme des données à l’aide de l’opérateur %, selon les
explications ci-dessous.
Le format s obéit exactement aux mêmes règles que dans les appels de la fonction printf(s, . . . ) du langage
C. Une explication détaillée de ces règles sortirait du cadre de ce petit polycopié. Pour débuter, il suffit de savoir
que
— %d indique un nombre entier, %nd un nombre entier cadré à droite dans une zone de n caractères,
— %f indique un nombre flottant, %nf un flottant cadré à droite dans une zone de n caractères, %n.mf un
flottant cadré à droite dans une zone de n caractères, ayant m chiffres après le point décimal,
— %c indique un caractère, %nc un caractère cadré à gauche dans une zone de n caractères,
— %s indique une chaı̂ne de caractères, %ns une chaı̂ne cadrée à gauche dans une zone de n caractères.
Session pour comprendre :
>>> x = 12.345678
>>> ’resultat: %f’ % x
'resultat: 12.345678'
>>> ’resultat: %12f’ % x
'resultat: 12.345678'
>>> ’resultat: %12.3f’ % x
'resultat: 12.346'
>>> ’%d/%02d/%4d’ % (5, 8, 2008)
'5/08/2008'
>>> ’x[%d] = %.2f’ % (i, x[i])
'x[8] = 123.45'
>>> ’chr(%d) = %c’ % (65, 65)
'chr(65) = A'
>>>
Quand on aborde les fichiers on s’intéresse pour la première fois à des données qui existent à l’extérieur de notre
programme. Du point de vue du programmeur, un fichier ouvert « en lecture » doit être vu comme un tube par
lequel arrivent des données extérieures chaque fois que le programme les demande, de même qu’il faut voir un
fichier ouvert « en écriture » comme un tube par lequel s’en vont à l’extérieur les données que le programme y
dépose.
On notera que cette approche permet de voir comme des fichiers le clavier et l’écran du poste utilisé. Cependant,
les fichiers auxquels on pense d’abord sont ceux enregistrés sur des supports non volatils (disques durs, clés USB,
26 © H. Garreta, 2014
TABLE DES MATIÈRES 6. ENTRÉES-SORTIES
cédéroms, etc.). Ils représentent des ensembles de données extérieures au programme, qui existent déjà quand
l’exécution de celui-ci démarre et qui ne disparaissent pas quand celle-ci se termine.
Pour les fonctions de la bibliothèque Python tout fichier est considéré comme séquentiel, c’est-à-dire constitué
par une succession d’informations lues ou écrites les unes à la suite des autres. Une fois qu’un fichier a été ouvert
par un programme, celui-ci maintient constamment une position courante, représentée par un « pointeur » (fictif)
qui indique constamment le prochain octet qui sera lu ou l’endroit où sera déposé le prochain octet écrit. Chaque
opération de lecture ou d’écriture fait avancer ce pointeur.
Voici les principales fonctions pour le traitement des fichiers :
fichier .read()
Lit tout le contenu du fichier indiqué et le renvoie sous forme de chaı̂ne de caractères.
Attention, cette fonction ne convient qu’aux fichiers de taille raisonnable, dont le contenu tient dans la
mémoire de l’ordinateur.
fichier .readline()
Lit une ligne du fichier indiqué (lors du premier appel la première ligne, au second appel la deuxième,
etc.).
Attention. Dans les fichiers de texte, la fin de chaque ligne est indiquée par un caractère spécial, qu’on peut
noter '\n' dans les programmes. En toute rigueur cette marque ne fait pas partie de la ligne, cependant
les fonctions readline et readlines l’ajoutent à la fin de la ligne lue et le renvoient dans le résultat : ne
pas oublier de l’enlever si nécessaire (voyez les exemples de la section suivante).
fichier .readlines()
Lit tout le contenu du fichier indiqué et le renvoie sous la forme d’une liste de chaı̂nes de caractères (une
chaı̂ne par ligne).
fichier .write(chaı̂ne)
Écrit la chaı̂ne indiquée dans le fichier en question.
fichier .writelines(séquence)
Écrit les chaı̂nes composant la séquence (liste, tuple, ensemble, etc.) de chaı̂nes donnée dans le fichier
indiqué.
fichier .close()
Ferme le fichier indiqué.
Prendre garde au fait que tant qu’un fichier nouvellement créé (c’est-à-dire un fichier ouvert en écriture)
n’a pas été fermé son statut dans le système n’est pas bien défini : le fichier peut ne pas apparaı̂tre sur
le disque dur, ou ne pas être complet, etc. Pour un fichier en écriture, l’appel final de close est donc
obligatoire.
© H. Garreta, 2014 27
6. ENTRÉES-SORTIES TABLE DES MATIÈRES
• Exemple de script 14. Vérifier le succès de l’ouverture du fichier et lire les lignes d’un fichier de texte.
def lireLignes(nomFichier):
try:
fic = open(nomFichier, 'r')
except IOError:
print (nomFichier + " : ce fichier n'existe pas")
return None
texte = fic.readlines()
fic.close();
return [ t[:-1] for t in texte ]
texte = lireLignes('MonTexte.txt')
if texte = None : !
for ligne in texte:
print (ligne)
Un exposé sur les exceptions du langage Python sortirait du cadre de ce petit polycopié ; on peut cependant
comprendre ce qui est fait dans cet exemple : l’instruction « fic = open(nomFichier, "r") » est enfermée
dans un bloc try...except destiné à attraper une éventuelle erreur (on dit plutôt exception) de type IOError
(erreur d’entrée-sortie). Si une telle erreur est effectivement déclenchée, un message est affiché et la fonction
renvoie None. S’il n’y a pas d’erreur le bloc try...except devient sans effet.
En cas de succès de l’ouverture du fichier, la fonction lit toutes ses lignes par un unique appel de readlines
puis ferme le fichier, devenu inutile.
L’expression « return [ t[:-1] for t in texte ] » finale mérite une explication. Il faut se souvenir que
readlines laisse à la fin de chaque ligne une marque '\n' qu’il faut enlever si on veut faire les choses proprement.
D’où notre expression : si t est une chaı̂ne, t[:-1] produit la chaı̂ne obtenue en enlevant le dernier caractère
et [ t[:-1] for t in texte ] la séquence obtenue en faisant cela sur chaque ligne de texte.
• Exemple de script 15. Lire des lignes avec des conditions. Lorsque le nombre de lignes d’un fichier risque
d’être très élevé, ou bien lorsque toutes les lignes ne sont pas acceptables, on ne peut pas utiliser la fonction
readlines.
La fonction suivante lit dans un fichier les nombreMax premières lignes qui ne commencent pas par le caractère
#, ou moins si le fichier n’a pas autant de telles lignes. On suppose ici que l’éventuel échec de l’ouverture du
fichier n’a pas à être traitée spécifiquement (on le laisse afficher des messages en anglais et tuer le programme).
28 © H. Garreta, 2014
TABLE DES MATIÈRES 6. ENTRÉES-SORTIES
texte = []
uneLigne = fic.readline()
while len(texte) < nombreMax and uneLigne != '' :
if uneLigne[0] != '#' :
texte.append( uneLigne[:-1] )
uneLigne = fic.readline()
fic.close();
return texte
remarquer comme la fin du fichier est détectée : aussi longtemps que le fichier n’est pas fini, le résultat renvoyé
par fic.readline() n’est pas la chaı̂ne vide, puisqu’il y a au moins le caractère \n qui marque la fin de la ligne.
Donc la production d’une ligne vide (pour laquelle la condition uneLigne != '' deviendra fausse) ne signifie
que l’échec de la lecture, le fichier étant fini.
• Exemple de script 16. Lire un fichier de nombres. L’exercice n’a pas une grande difficulté mais nous en
donnons ici une solution car il s’agit d’un problème extrêmement fréquent dans les applications.
Nous supposons que les lignes du fichier n’ont pas une structure fixe mais qu’elles sont « propres » : il n’y a que
des nombres et des caractères blancs (espaces, tabulations et fins de ligne) qui les séparent, comme ceci :
2.5 3 5.25 8
-0.5
Script :
def lectureNombres(nomFichier):
resultat = []
fichier = open(nomFichier, "r")
while True:
ligne = fichier.readline()
if ligne == '':
break
for mot in ligne.split():
if mot.find('.') >= 0:
resultat.append(float(mot))
else:
resultat.append(int(mot))
fichier.close()
return resultat
s = lectureNombres("nombres.txt")
print ([ (t, type(t)) for t in s ])
© H. Garreta, 2014 29
6. ENTRÉES-SORTIES TABLE DES MATIÈRES
• Exemple de script 17. Produire un fichier de nombres. Avec ce que nous savons déjà, aucune difficulté pour
l’enregistrement dans un fichier d’une collection de nombres, même lorsqu’on nous impose une mise en forme
compliquée.
La fonction suivante reçoit un nom de fichier et trois séquences X, Y , Z (supposées de même longueur) de
nombres flottants et produit un fichier de texte où chaque ligne porte un entier i et un triplet (X[i], Y [i], Z[i])
présentés de la manière suivante :
Script :
30 © H. Garreta, 2014
Master Sciences Cognitives
7 Modules
Tout fichier contenant du code python, dont le nom se termine par .py, constitue un module.
Le contenu d’un fichier peut être importé à l’aide de la directive import.
Si vous avez créé le fichier MonModule.py, vous pourrez utiliser son contenu en l’important dans un autre fichier 5
de la manière suivante :
import MonModule
Cela provoque l’exécution du code contenu dans MonModule.py et permet d’accéder aux variables et aux fonc-
tions définies dans MonModule.py.
L’accès aux fonctions et variables définies dans MonModule.py depuis le programme appelant est réalisée de la
manière suivante MonModule.x où x est l’identifiant de la variable ou de la fonction que vous souhaitez appeler.
Il est aussi possible d’importer juste certains éléments d’un module, à l’aide de la directive :
Dans ce cas, seule la fonction ou la variable x est importée et l’accès à cette dernière est réalisée plus simplement,
sans devoir préfixer x par le nom du module, comme c’était le cas ci-dessus.
Attention dans ce cas la variable ou la fonction importée depuis le module peut masquer une variable ou une
fonction définie dans le programme appelant.
Vous pouvez aussi importer l’ensemble des variables et fonctions d’un module et d’y avoir accès sans spécifier
le nom du module de la manière suivante :
Il est possible de connaı̂tre toutes les variables et fonctions importées depuis un module à l’aide de la fonction
dir.
dir(MonModule)
© H. Garreta, 2014 31
Master Sciences Cognitives
8 Classes
Les classes constituent un moyen de réunir des variables et des fonctions au sein d’un nouveau type d’entité,
appelé objet ou instance d’une classe.
Les classes sont définies à l’aide de la directive class.
A l’intérieur d’une classe, on peut trouver des variables, aussi appelées variables d’instances et des fonctions
aussi appelée méthodes.
Voici un exemple d’une classe simple permettant de définir un point par ses coordonnées dans le plan euclidien.
class Point:
x = 0
y = 0
def affiche(self):
print("x = ", self.x, "y = ", self.y)
La classe Point définit deux variables judicieusement nommées x et y, représentant les coordonnées du point.
Ces deux variables sont initialisées à zéro.
La classe Point définit aussi deux fonctions, ou méthodes, appelées translation et affiche.
On pourra noter dans ces dernières la syntaxe particulière, qui rappelle les modules : self.x. Cette construction
fait référence à la variable x d’une instance particulière de point, sur laquelle nous renviendrons ci-dessous,
appelée self.
Pour créer un point particulier, ou instance de la classe Point, et l’affecter à une variable. On s’y prend de la
manière suivante :
p = Point()
On peut maintenant appeler les méthodes définies dans la classe Point à partir de notre variable p. Cela se fait
de la manière suivante :
p.translation(3,2)
p.affiche()
La syntaxe est la même que pour l’accès aux variables d’une instance x : x.nomDeLaMethode(arguments).
Une méthode ne peut être appelée qu’à partir d’une instance de la classe concernée.
Il est généralement nécessaire de faire référence à cette instance dans la définition de la méthode.
Par exemple, dans la méthode affiche, il faut pouvoir accèder aux coordonnées de l’instance de point que l’on
souhaite afficher.
Pour cela, on ajoute aux méthodes un argument particulier, conventionnellement nommé self (que l’on pourrait
appeler moi), qui désigne l’instance à partir de laquelle la méthode a été appelée.
Cet argument doit être le premier argument formel dans la définition de la méthode.
L’argument self n’apparaı̂t avec les autres arguments lors d’un appel de méthode.
Ainsi, dans la définition de la classe Point la méthode translation possède trois arguments : self, dx et dy.
Mais lors de l’appel, seuls les deux dernier arguments sont spécifiés entre parenthèses.
32 © H. Garreta, 2014
TABLE DES MATIÈRES 8. CLASSES
Le premier est l’instance à partir de laquelle la méthode a été appelée, c’est lui qui correspond à l’argument
self.
Il est aussi possible d’appeler une méthode m() d’une instance i d’un classe C en utilisant la syntaxe suivante :
C.m(i), comme ci-dessous :
Point.translation(p,3,2)
Point.affiche(p)
Ce n’est pas particulièrement joli et c’est plus long, mais on verra plus bas que c’est utile dans certains cas.
8.1 Constructeurs
Il est souvent pratique de pouvoir initialiser les variables d’une instance lors de la création de cette dernière.
Pour cela, on peut définir des méthodes particulières appelées constructeurs.
Les constructeurs possèdent un nom particulier __init__ et peuvent avoir un nombre quelconque de paramètres,
comme dans l’exemple suivant :
Un constructeur est appelé de manière implicite lors de la création d’une instance, il n’est pas nécessaire de faire
un appel explicite à la méthode __init__, comme dans l’exemple suivant :
p = Point(2,3)
Lorsqu’un constructeur est défini pour une classe, ce qui est conseillé, il n’est plus nécessaire de définir les
variables d’instance de manière explicite, c’est lors de l’appel au constructeur que celles-ci sont définies.
La classe Point devient :
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
La classe Point comportait la méthode affiche qui permet de représenter ce que l’on considère important d’un
point particulier.
Python offre un mécanisme plus général de représentation d’une instance sous la forme d’une chaı̂ne de carac-
tères.
Il s’agit la méthode __str__, qui prend comme seul paramètre self et retourne une chaı̂ne de caractère, comme
dans l’exemple ci-dessous :
def __str__(self):
return "(x = %d, y = %d)" % (self.x, self.y)
La méthode __str__ peut être appelée, comme toute autre méthode, à partir d’une instance de point :
>>> p = Point(3,2)
>>> p.__str__()
'(x = 3 y = 2)'
© H. Garreta, 2014 33
8. CLASSES TABLE DES MATIÈRES
Mais son véritable intérêt est qu’elle est appelée automatiquement par Python pour obtenir la représentation
d’un point sour la forme d’une chaı̂ne de caractères, par exemple pour l’afficher à l’aide de la fonction print,
comme dans l’exemple suivant :
>>> p = Point(3,2)
>>> print ("point = ", p)
point = (x = 3, y = 2)
8.3 Héritage
On peut être amené dans certains cas à définir des classes qui partagent un certain nombre de variables ou de
méthodes.
Supposons par exemple que nous voulions définir un lexique (un ensemble de mots) et que les mots composant
notre lexique aient des caractéristiques différentes selon leur catégorie.
On spécifiera, par exemple, pour un verbe son groupe, pour un nom, son genre . . .
La programmation objet offre pour cela un mécanisme appelé héritage qui permet à une classe d’hériter des
propriétés d’une classe plus générale, appelée classe mère ou superclasse.
Dans l’exemple précédent, on pourrait définir une classe générale, appelée Mot et des classes plus spécifiques
appelées Verbe, Adjectif, Déterminant . . .
Lors de la définition d’une classe, on indique sa classe mère entre parenthèses, comme dans l’exemple suivant :
class Mot:
def __init__(self, graphie, langue = "français", registre = "normal"):
self.graphie = graphie
self.langue = langue
self.registre = registre
def __str__(self):
return "graphie = %s, langue = %s , registre = %s" % (self.graphie, self.langue, self.registre)
class Verbe(Mot):
def __init__(self, graphie, groupe):
Mot.__init__(self, graphie)
self.groupe = groupe
def __str__(self):
return Mot.__str__(self) + " categorie = verbe, groupe = %d" % (self.groupe)
class Nom(Mot):
def __init__(self, graphie, genre):
Mot.__init__(self, graphie)
self.genre = genre
def __str__(self):
return Mot.__str__(self) + " categorie = nom, genre = %s" % (self.genre)
Trois classes sont définies dans cet exemple : Mot, Verbe et Nom.
La classe Mot définit trois variables d’instances : graphie, langue et registre et deux méthodes : le constructeur
__init__ et la méthode de conversion __str__.
La classe Verbe hérite de la classe Mot ses variables et ses méthodes.
La classe Verbe définit son propre constructeur, mais ce dernier réalise un appel au constructeur de sa super-
classe.
34 © H. Garreta, 2014
Master Sciences Cognitives
9 Exceptions
Dans certains cas, un programme Python rencontre une erreur qui provoque l’interruption de ce dernier, par
exemple lorsqu’on essaye d’accéder à un élément d’une chaı̂ne de caractère qui est supérieur ou égal à la longueur
de celle-ci.
>>> s = 'bonjour'
>>> i = 7
>>> s[i]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>>
Lorsque l’erreur se produit, l’interpréteur Python crée une exception, on dit en général, qu’il lance ou qu’il lève
une exception. Dans l’exemple précédent, il s’agit de l’exception IndexError.
Si l’on ne veut pas que cette erreur, provoque l’arrêt du programme, on peut inclure le code dans un bloc try
... except, comme dans l’exemple ci-dessous.
s = 'bonjour'
i = 7
try:
s[i]
except IndexError:
print("l'index ", i, "n'est pas valide")
Si dans le corps du try l’exception IndexError est lancée, elle sera attrapée par la clause except IndexError
et les instructions se trouvant dans le corps de ce except seront exécutées.
Dans l’exemple précédent, l’exception est lancée par l’interpréteur Python, mais il est possible de provoquer
intentionnellement le lancement d’une exception grâce à l’instruction raise qui lance une exception, comme
dans l’exemple suivant, qui n’est pas très intéressant mais permet d’illustrer le propos :
s = 'bonjour'
i = 7
try:
if i >= len(s):
raise IndexError
except IndexError:
print("l'index ", i, "n'est pas valide")
Dans cet exemple, l’accès à un caractère inexistant de la chaı̂ne est détecté par le programme et non par
l’interpréteur Python.
Dans les deux exemples précédents, l’exception lancée est une exception définie par Python.
Il est aussi possible de définir de nouvelles exceptions.
Celles-ci se présentent sous la forme de classes qui ont pour ancêtre (direct ou indirect) la classe Exception,
comme dans l’exemple suivant.
© H. Garreta, 2014 35
9. EXCEPTIONS TABLE DES MATIÈRES
except MonException:
print("l'index ", i, "n'est pas valide")
Dans cet exemple, la classe MonException ne définit rien du tout (c’est ce qu’indique la directive pass).
36 © H. Garreta, 2014
Master Sciences Cognitives
10 Annexes
Voici des tableaux récapitulatifs des opérations sur les séquences. Il y a six types de séquences (certains ignorés
dans le cadre de ce cours) : les chaı̂nes de caractères, les chaı̂nes de caractères Unicode, les listes, les tuples,
les buffers et les objets range. Tous ces types représentent des séquences immuables sauf les listes qui, elles,
supportent les modifications.
Pour des précisions supplémentaires, voyez la section 3.6 du manuel Python Library Reference (cf. http://
docs.python.org/lib/typesseq.html)
Opérations additionnelles sur les listes. En tant que séquences modifiables, les listes supportent en plus
les opérations suivantes :
© H. Garreta, 2014 37
10. ANNEXES TABLE DES MATIÈRES
38 © H. Garreta, 2014