Cours Python3
Cours Python3
Cours Python3
Introduction à Python 3
version 2.71828
bcordeau@numericable.fr
Informatique :
Maurice Nivat
Remerciements :
Sans les encouragements de Gérard Swinnen, jamais je n’aurais osé me lancer dans l’aventure
de l’enseignement de Python. Qu’il en soit remercié.
Ce document a bénéficié des corrections impitoyables de Laurent Pointal (LIMSI), des lec-
tures attentives de Michelle Kessous, de Michelle Cordeau et de Georges Vincents (IUT
d’Orsay, département Mesures Physiques).
Grand merci à ma fille Hélène pour ses illustrations ; les aventures de Steven le Python en-
chantent les têtes de paragraphe.
Merci à Tarek Ziadé pour les emprunts à ses publications, en particulier je remercie les édi-
tions Eyrolles pour leur aimable autorisation de publier le dialogue de la page 102, ainsi que
les éditions Dunod pour leur aimable autorisation de publier les exemples des pages 88, 90,
96 et 98.
Enfin il me faudrait saluer tous les auteurs que j’ai butinés sur Internet... Qu’au moins, je
n’oublie pas ceux à qui j’ai fait les plus grands emprunts dans les annexes : Sebsauvage et
Christian Schindelhauer.
Avant-propos
Ce cours prend la suite des « Notes de cours Python 2 » destiné aux étudiants de Mesures
Physiques de l’IUT d’Orsay.
Bien qu’à ce jour l’offre des bibliothèques tierces ne soit pas pas encore riche (entre autres
la bibliothèque numpy n’est pas disponible), il semble utile de disposer d’un cours généraliste
en français consacré à la version 3 de Python.
Nous en avons profité pour étoffer le texte de trois chapitres et pour proposer une forme plus
pratique pour un texte suceptible d’être imprimé, tout en restant agréable à consulter à l’écran.
Outre ce cadre universitaire assez réduit, ce cours s’adresse à toute personne désireuse
d’apprendre Python en tant que premier langage de programmation.
Licence :
Ce cours est mis à disposition selon le Contrat Paternité 2.0 France disponible en ligne
creativecommons.org/licenses/by/2.0/fr/ ou par courrier postal à Creative Commons, 171
Second Street, Suite 300, San Francisco, California 94105, USA.
1. C’est une grave décision, mûrement réfléchie : « Un langage qui bouge peu permet une industrie qui
bouge beaucoup » (Bertrand Meyer)
2. disponibles à l’adresse http ://www.iut-orsay.fr/dptmphy/Pedagogie/coursPython.pdf.
3. spécialement sa version Wing IDE 101, gratuite pour toutes les plateformes.
Table des matières
1 Introduction 1
1.1 Principales caractéristiques du langage Python . . . . . . . . . . . . . . . 1
1.2 Matériel et logiciel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1 L’ordinateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.2 Deux sortes de programmes . . . . . . . . . . . . . . . . . . . . . 2
1.3 Les langages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.1 Des langages de différents niveaux . . . . . . . . . . . . . . . . . 3
1.3.2 Bref historique des langages . . . . . . . . . . . . . . . . . . . . . 3
1.4 Production des programmes . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.1 Deux techniques de production des programmes . . . . . . . . . . 3
1.4.2 Technique de production de Python . . . . . . . . . . . . . . . . . 4
1.4.3 La construction des programmes . . . . . . . . . . . . . . . . . . 4
1.5 Algorithme et programme . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5.1 Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5.2 La présentation des programmes . . . . . . . . . . . . . . . . . . 5
1.6 Les implémentations de Python . . . . . . . . . . . . . . . . . . . . . . . 5
2 La calculatrice Python 7
2.1 Les modes d’exécution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.1 Les deux modes d’exécution d’un code Python . . . . . . . . . . . 7
2.2 Identifiants et mots clés . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 Identifiants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.2 Style de nommage . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.3 Les mots réservés de Python 3 . . . . . . . . . . . . . . . . . . . 9
2.3 Notion d’expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 Les types de données entiers . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.1 Le type int . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.2 Le type bool . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 Les types de données flottants . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5.1 Le type float . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5.2 Le type complex . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Variables et affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.1 Les variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.2 L’affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.3 Affecter n’est pas comparer ! . . . . . . . . . . . . . . . . . . . . 12
2.6.4 Les variantes de l’affectation . . . . . . . . . . . . . . . . . . . . 13
2.6.5 Les affectations (explications graphiques) . . . . . . . . . . . . . . 13
2.7 Les chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . 13
iii
iv TABLE DES MATIÈRES
6 Modules et packages 47
6.1 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.1.1 Import d’un module . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.1.2 Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6.2 Bibliothèque standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6.2.1 La bibliothèque standard . . . . . . . . . . . . . . . . . . . . . . 49
6.3 Bibliothèques tierces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.3.1 Une grande diversité . . . . . . . . . . . . . . . . . . . . . . . . 52
6.3.2 Un exemple : la bibliothèque Unum . . . . . . . . . . . . . . . . . 52
6.4 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
8 Techniques avancées 65
8.1 Techniques procédurales . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.1.1 Améliorer la documentation . . . . . . . . . . . . . . . . . . . . . 65
8.1.2 Faire des menus avec un dictionnaire . . . . . . . . . . . . . . . . 66
8.1.3 Les fonctions récursives . . . . . . . . . . . . . . . . . . . . . . . 67
8.1.4 Les générateurs et les expressions génératrices . . . . . . . . . . . 69
8.1.5 Les fonctions incluses . . . . . . . . . . . . . . . . . . . . . . . . 70
8.1.6 Les décorateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
8.2 Techniques objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.2.1 __slots__ et __dict__ . . . . . . . . . . . . . . . . . . . . 72
8.2.2 Functor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.2.3 Les accesseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
8.3 Techniques fonctionnelles . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.3.1 Directive lambda . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.3.2 Les fonctions map, filter et reduce . . . . . . . . . . . . . . 75
8.3.3 Les applications partielles de fonctions . . . . . . . . . . . . . . . 76
9 La programmation « OO » graphique 79
9.1 Programmes pilotés par des événements . . . . . . . . . . . . . . . . . . . 79
9.2 La bibliothèque tkinter . . . . . . . . . . . . . . . . . . . . . . . . . 80
9.2.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
9.2.2 Les widgets de tkinter . . . . . . . . . . . . . . . . . . . . . 80
9.2.3 Le positionnement des widgets . . . . . . . . . . . . . . . . . . . 81
9.3 Deux exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
9.3.1 tkPhone, un exemple sans menu . . . . . . . . . . . . . . . . . 81
9.3.2 IDLE, un exemple avec menu . . . . . . . . . . . . . . . . . . . 85
A Interlude 101
G Ressources 129
TABLE DES MATIÈRES vii
H Glossaire 133
Colophon 143
viii TABLE DES MATIÈRES
Table des figures
8.1 Empilage/dépilage de 4 ! . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.2 Application partielle d’un widget . . . . . . . . . . . . . . . . . . . . . . . 77
ix
x TABLE DES FIGURES
Introduction à l’informatique
Définition
å Automate déterministe à composants électroniques.
• Le système d’exploitation : ensemble des programmes qui gèrent les ressources maté-
rielles et logicielles. Il propose une aide au dialogue entre l’utilisateur et l’ordinateur :
l’interface textuelle (interpréteur de commande) ou graphique (gestionnaire de fe-
nêtres). Il est souvent multitâche et parfois multiutilisateur ;
1.3. LES LANGAGES 3
• les programmes applicatifs sont dédiés à des tâches particulières. Ils sont formés d’une
série de commandes contenues dans un programme source qui est transformé pour être
exécuté par l’ordinateur.
Dans la technique de l’interprétation chaque ligne du source analysé est traduite au fur et
à mesure en instructions directement exécutées. Aucun programme objet n’est généré. Cette
technique est très souple mais les codes générés sont peu performants : l’interpréteur doit
être utilisé à chaque exécution...
4 CHAPITRE 1. INTRODUCTION
Pour exécuter un programme, Python charge le fichier source .py (ou .pyw) en mé-
moire vive, en fait l’analyse syntaxique, produit le bytecode et enfin l’exécute. Pour chaque
module importé par le programme, Python vérifie d’abord s’il existe une version précompi-
lée du bytecode (dans un fichier .pyo ou .pyc) dont la date correspond au fichier .py. S’il
y en a un, Python l’utilise, sinon il fait une analyse syntaxique du module .py, et utilise le
bytecode qu’il vient de générer.
En pratique, il n’est pas nécessaire de compiler explicitement un module, Python gère ce
mécanisme de façon transparente.
La signification de parties non triviales (et uniquement celles-ci) doit être expliquée par
un commentaire.
Un commentaire commence par le caractère # et s’étend jusqu’à la fin de la ligne :
#---------------------
# Voici un commentaire
#---------------------
9 + 2 # En voici un autre
La calculatrice Python
Comme tout langage, Python permet de manipuler des données grâce à un vo-
cabulaire de mots réservés et grâce à des types de données – approximation des
ensembles de définition utilisés en mathématique.
Ce chapitre présente les règles de construction des identifiants, les types de don-
nées simples (les conteneurs seront examinés au chapitre 4) ainsi que les types
chaîne de caractères (Unicode et binaires).
Enfin, last but not least, ce chapitre s’étend sur les notions non triviales de va-
riables, de références d’objet et d’affectation.
Définition
å Un identifiant Python est une suite non vide de caractères, de longueur quelconque,
formée d’un caractère de début et de zéro ou plusieurs caractères de continuation.
Sachant que :
• un caractère de début peut être n’importe quelle lettre Unicode (cf. annexe B p. 105),
ainsi que le caractère souligné (_) ;
• un caractère de continuation est un caractère de début, un chiffre ou un point.
Attention
' Les identifiants sont sensibles à la casse et ne doivent pas être un mot clé.
Exemples :
NB_ITEMS = 12 # UPPER_CASE
class MaClasse: pass # TitleCase
def maFonction(): pass # camelCase
mon_id = 5 # lower_case
id1 = 15.3
id2 = maFonction(id1)
if id2 > 0:
id3 = math.sqrt(id2)
else:
id4 = id1 - 5.5*id2
Les entiers littéraux sont décimaux par défaut, mais on peut aussi utiliser les bases sui-
vantes (cf. p. 111) :
Opérations arithmétiques
Bases usuelles
Un entier écrit en base 10 (par exemple 179) peut se représenter en binaire, octal et
hexadécimal en utilisant les syntaxes suivantes :
>>> 0b10110011 # binaire
179
>>> 0o263 # octal
179
>>> 0xB3 # hexadécimal
179
• Les opérations logiques et de comparaisons sont évaluées afin de donner des résultats
booléens dans False, True.
2.5. LES TYPES DE DONNÉES FLOTTANTS 11
print(math.sin(math.pi/4)) # 0.7071067811865475
print(math.degrees(math.pi)) # 180.0
print(math.factorial(9)) # 362880
print(math.log(1024, 2)) # 10.0
Définition
å Une variable est un identifiant associé à une valeur.
Informatiquement, c’est une référence d’objet située à une adresse mémoire.
2.6.2 L’affectation
Définition
å On affecte une variable par une valeur en utilisant le signe = (qui n’a rien à voir avec
l’égalité en math !). Dans une affectation, le membre de gauche reçoit le membre de droite
ce qui nécessite d’évaluer la valeur correspondant au membre de droite avant de l’affecter au
membre de gauche.
a = 2 # prononcez : a ”reçoit” 2
b = 7.2 * math.log(math.e / 45.12) - 2*math.pi
c = b ** a
La valeur d’une variable, comme son nom l’indique, peut évoluer au cours du temps (la
valeur antérieure est perdue) :
a = a + 1 # 3 (incrémentation)
a = a - 1 # 2 (décrémentation)
La comparaison a une valeur utilisable dans une expression mais n’a pas d’effet (l’automate
interne représentant l’évolution du programme n’est pas modifié) :
>>> x = (a == 3) + 2
>>> x
2
2.7. LES CHAÎNES DE CARACTÈRES 13
# affectation simple
v = 4
# affectation augmentée
v += 2 # idem à : v = v + 2 si v est déjà référencé
Les affectations relient les identificateurs aux données : si une donnée en mémoire n’est
plus reliée, le ramasse-miettes (garbage collector) de Python la supprime automatiquement :
code.
Non modifiable signifie qu’une donnée, une fois créée en mémoire, ne pourra plus être chan-
gée.
• Concaténation :
s1 = ”abc”
s2 = ”defg”
s3 = s1 + s2 # ’abcdefg’
• Répétition :
s4 = ”Fi! ”
s5 = s4 * 3 # ’Fi! Fi! Fi! ’
print(s5)
La notation [xxx] indique un élément optionnel que l’on peut donc omettre lors de l’utilisation
de la méthode.
• isupper() et islower() : retournent True si ch ne contient respectivement
que des majuscules/minuscules :
print(”cHAise basSe”.isupper()) # False
Bien différencier les codes, glyphes, caractères et octets ! (Cf. Fig. 2.5)
formations, ce qui est généralement fait depuis une lecture au clavier. Inversement, on doit
pouvoir afficher ou sortir des informations, ce qui correspond généralement à une écriture
sur l’écran.
f1 = input(”\nEntrez un flottant : ”)
f1 = float(f1) # transtypage en flottant
# ou plus brièvement :
f2 = float(input(”Entrez un autre flottant : ”))
print(type(f2)) # <class ’float’>
a, b = 2, 5
print(a, b) # 2 5
print(”Somme :”, a + b) # Somme : 7
print(a - b, ”est la différence”) # -3 est la différence
print(”Le produit de”, a, ”par”, b, ”vaut :”, a * b)
# Le produit de 2 par 5 vaut : 10
print() # affiche une nouvelle ligne
# pour afficher un espace à la place de la nouvelle ligne:
print(a, end=” ”) # 2 (et ne va pas à la ligne)
print(”\nErreur fatale !”, file=sys.stderr) # dans un fichier
print(”On a <”, 2**32, ”> cas !”, sep=”###”)
# On a <###4294967296###> cas !
Séquence Signification
\saut_ligne saut de ligne ignoré
\\ affiche un antislash
\’ apostrophe
\” guillemet
\a sonnerie (bip)
\b retour arrière
\f saut de page
\n saut de ligne
\r retour en début de ligne
\t tabulation horizontale
\v tabulation verticale
\N{nom} caractère sous forme de code Unicode nommé
\uhhhh caractère sous forme de code Unicode 16 bits
\Uhhhhhhhh caractère sous forme de code Unicode 32 bits
\ooo caractère sous forme de code octal
\xhh caractère sous forme de code hexadécimal
Exemples :
20 CHAPITRE 2. LA CALCULATRICE PYTHON
Chaque ligne d’instructions est formée d’une ou plusieurs lignes physiques qui
peuvent être continuées par un antislash \ ou un caractère ouvrant [({ pas encore
fermé.
Cette exécution en séquence peut être modifiée pour choisir ou répéter des por-
tions de code. C’est l’objet principal de ce chapitre.
Attention
' Toutes les instructions au même niveau d’indentation appartiennent au même bloc (cf.
Fig. 3.1).
22 CHAPITRE 3. LE CONTRÔLE DU FLUX D’INSTRUCTIONS
Exemple :
somme = 0.0
nb_valeurs = 0
for v in valeurs:
nb_valeurs = nb_valeurs + 1
somme = somme + valeurs
3.2 Choisir
3.2.1 Choisir : if - [elif] - [else]
Contrôler une alternative :
if x < 0:
print(”x est négatif”)
3.3. BOUCLER 23
elif x % 2:
print(”x est positif et impair”)
else:
print(”x n’est pas négatif et est pair”)
# Ecriture classique :
if x < y:
plus_petit = x
else:
plus_petit = y
3.3 Boucler
3.3.1 Boucler : while
Répéter une portion de code :
x, cpt = 257, 0
print(”L’approximation de log2 de”, x, ”est”, end=” ”)
while x > 1:
x //= 2 # division avec troncature
cpt += 1 # incrémentation
print(cpt, ”\n”) # 8
Utilisation classique : la saisie filtrée d’une valeur numérique (on doit préciser le type car
input() saisit une chaîne) :
n = int(input(’Entrez un entier [1 .. 10] : ’))
while not(1 <= n <= 10):
n = int(input(’Entrez un entier [1 .. 10], S.V.P. : ’))
for i in range(5):
print(i, end=” ”) # 0 1 2 3 4
# affiche :
# 1 2 3 4
# Boucle interrompue pour x = 5
# affiche :
# 1 2 3 4 6 7 8 9 10
# La boucle a sauté la valeur 5
x = y // 2
while x > 1:
if y % x == 0:
print(”{} a pour facteur {}”.format(y, x))
break # voici l’interruption !
x -= 1
else:
print(y, ”est premier.”)
for - else
Un exemple avec le parcours d’une liste :
for i in une_sequence:
if i == cible:
sauve = i
break # voici l’interruption !
else:
print(cible, ”n’est pas dans”, une_sequence)
sauve = None
3.4.4 Exceptions
Afin de rendre les applications plus robustes, il est nécessaire de gérer les erreurs d’exécution
des parties sensibles du code.
Le mécanisme des exceptions sépare d’un côté la séquence d’instructions à exécuter
lorsque tout se passe bien et, d’un autre côté, une ou plusieurs séquences d’instructions à
exécuter en cas d’erreur.
Lorsqu’une erreur survient, un objet exception est passé au ménanisme de propagation
des exceptions, et l’exécution est transférée à la séquence de traitement ad hoc.
Le mécanisme s’effectue en deux phases :
• la levée d’exception lors de la détection d’erreur ;
• le traitement approprié.
Syntaxe
. La séquence normale d’instructions est placée dans un bloc try.
Si une erreur est détectée (levée d’exception), elle est traitée dans le bloc except approprié
(le gestionnaire d’exception).
Toutes les exceptions levées par Python sont des instances de sous-classe de la classe
Exception. La hiérarchie des sous-classes offre une vingtaine d’exceptions standard 1 .
Remarque
3 raise, sans valeur, dans un bloc except, permet de ne pas bloquer une exception, de
la propager.
Bloc gardé (ou gestionnaire de contexte) :
Cette syntaxe simplifie le code en assurant que certaines opérations sont exécutées avant
et après un bloc d’instructions donné. Illustrons ce mécanisme sur un exemple classique ou
il importe de fermer le fichier utilisé :
# au lieu de ce code :
fh = None
try:
fh = open(filename)
for line in fh:
process(line)
except EnvironmentError as err:
print(err)
finally:
if fh is not None:
fh.close()
Le chapitre 2 a présenté les types de données simples, mais Python offre beaucoup
plus : les conteneurs.
De façon générale, un conteneur est un objet composite destiné à contenir d’autres
objets. Ce chapitre détaille les séquences, les tableaux associatifs, les ensembles
et les fichiers textuels.
Syntaxe
. Éléments séparés par des virgules, et entourés de crochets.
l1 = list(range(4))
print(”l1 =”, l1) # l1 = [0, 1, 2, 3]
l2 = list(range(4, 8))
print(”l2 =”, l2) # l2 = [4, 5, 6, 7]
l3 = list(range(2, 9, 2))
print(”l3 =”, l3) # l3 = [2, 4, 6, 8]
for i in range(len(l3)):
print(i, l3[i], sep=”-”, end=” ”) # 0-2 1-4 2-6 3-8
4.2.3 Méthodes
Quelques méthodes de modification des listes :
une tranche dans le membre de gauche d’une affectation et fournir une liste dans le membre
de droite.
mots = [’jambon’, ’sel’, ’miel’, ’confiture’, ’beurre’]
Syntaxe
. Éléments séparés par des virgules, et entourés de parenthèses.
• Les tuples s’utilisent comme les listes mais leur parcours est plus rapide ;
• Ils sont utiles pour définir des constantes.
Attention
' Comme les chaînes de caractères, les tuples ne sont pas modifiables !
phrase[4] = ”casse”
Si l’on désire réaliser une vraie copie 1 d’un objet, on doit utiliser le module copy :
import copy
a = [1, 2, 3]
b = a # une référence
b.append(4)
print(a) # [1, 2, 3, 4]
c = copy.copy(a) # une copie de ”surface”
c.append(5)
print(c) # [1, 2, 3, 4, 5]
print(a) # [1, 2, 3, 4]
Dans les rares occasions où l’on veut aussi que chaque élément et attribut de l’objet soit
copié séparément et de façon récursive, on emploie la fonction copy.deepcopy().
Les dictionnaires constituent un type composite mais ils n’appartiennent pas aux sé-
quences.
Comme les listes, les dictionnaires sont modifiables, mais les couples enregistrés n’occupent
pas un ordre immuable, leur emplacement est géré par un algorithme spécifique (Cf. les fonc-
tions de hachage p. 113).
Une clé pourra être alphabétique, numérique. . . en fait tout type hachable. Les valeurs
pourront être des valeurs numériques, des séquences, des dictionnaires, mais aussi des fonc-
tions, des classes ou des instances.
Exemples de création
Méthodes
Quelques méthodes applicables aux dictionnaires :
tel = {’jack’: 4098, ’sape’: 4139}
tel[’guido’] = 4127
X, Y = set(’abcd’), set(’sbds’)
print(”X =”, X) # X = {’a’, ’c’, ’b’, ’d’}
print(”Y =”, Y) # Y = {’s’, ’b’, ’d’} : un seul élément ’s’
print(’c’ in X) # True
print(’a’ in Y) # False
print(X - Y) # {’a’, ’c’}
print(Y - X) # {’s’}
print(X | Y) # {’a’, ’c’, ’b’, ’d’, ’s’}
print(X & Y) # {’b’, ’d’}
Mais, pour conserver durablement des informations, il faut utiliser une mémoire perma-
nente comme par exemple le dique dur, la clé USB, le DVD,. . .
Comme la plupart des langages, Python utilise classiquement la notion de fichier. C’est
un type pré-défini en Python, qui ne nessécite donc pas d’importer de module externe.
Nous nous limiterons aux fichiers textuels (portables, lisible par un éditeur), mais signa-
lons que les fichiers stockés en codage binaire sont plus compacts et plus rapides à gérer.
Python utilise les fichiers en mode texte par défaut (noté t) (pour les fichiers binaires, il
faut préciser le mode b).
Le paramètre optionnel encoding assure les conversions entre les types byte et
str 1 . Les encodages les plus fréqents sont ’utf-8’ (c’est l’encodage à privilégier en
Python 3), ’latin1’, ’ascii’...
Tant que le fichier n’est pas fermé, son contenu n’est pas garanti sur le disque.
Une seule méthode de fermeture :
f1.close()
Écriture séquentielle
Méthodes d’écriture :
f = open(”truc.txt”, ”w”)
s = ’toto\n’
f.write(s) # écrit la chaîne s dans f
l = [’a’, ’b’, ’c’]
f.writelines(l) # écrit les chaînes de la liste l dans f
f.close()
Lecture séquentielle
Méthodes de lecture :
f = open(”truc.txt”, ”r”)
s = f.read() # lit tout le fichier --> string
s = f.read(3) # lit au plus n octets --> string
s = f.readline() # lit la ligne suivante --> string
1. Cf. l’annexe B
4.9. ITÉRER SUR LES CONTENEURS 35
Boucler sur une séquence inversée (la séquence initiale est inchangée) :
print()
for i in reversed(range(1, 10, 2)):
print(i, end=” ”) # 9 7 5 3 1
Boucler sur une séquence triée à éléments uniques (la séquence initiale est inchangée) :
print()
basket = [”apple”, ”orange”, ”apple”, ”pear”, ”orange”, ”banana”]
for f in sorted(set(basket)):
print(f, end=” ”) # apple banana orange pear
Formatages numériques :
print(”{0} {0:b} {0:o} {0:x}”.format(179)) # 179 10110011 263 b3�
n = 100
pi = 3.1415926535897931
print(”{:.4e}”.format(pi)) # 3.1416e+00
print(”{:g}”.format(pi)) # 3.14159
Formatages divers :
s = ”The sword of truth”
print(”[{}]”.format(s)) # [The sword of truth]
print(”[{:25}]”.format(s)) # [The sword of truth ]
print(”[{:>25}]”.format(s)) # [ The sword of truth]
print(”[{:^25}]”.format(s)) # [ The sword of truth ]
print(”[{:-^25}]”.format(s)) # [---The sword of truth----]
print(”[{:.<25}]”.format(s)) # [The sword of truth.......]
long = 12
print(”[{}]”.format(s[:long])) # [The sword of]
m = 123456789
print(”{:0=12}”.format(m)) # 000123456789
print(”{:#=12}”.format(m)) # ###123456789
38 CHAPITRE 4. LES CONTENEURS STANDARD
Chapitre 5
Remarque
3 Les fonctions sont les éléments structurants de base de tout langage procé-
dural.
Le bloc d’instructions est obligatoire. S’il est vide, on emploie l’instruction pass. La
documentation (facultative) est fortement conseillée.
40 CHAPITRE 5. FONCTIONS ET ESPACES DE NOMS
# exemple d’appel :
table(7, 2, 11)
# 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42
# 7 x 7 = 49 8 x 7 = 56 9 x 7 = 63 10 x 7 = 70 11 x 7 = 77
def cube(x):
return x**3
42 CHAPITRE 5. FONCTIONS ET ESPACES DE NOMS
def volumeSphere(r):
return 4.0 * pi * cube(r) / 3.0
def surfaceVolumeSphere(r):
surf = 4.0 * math.pi * r**2
vol = surf * r/3
return surf, vol
# programme principal
rayon = float(input(’Rayon : ’))
s, v = surfaceVolumeSphere(rayon)
print(”Sphère de surface {:g} et de volume {:g}”.format(s, v))
def maFonction(x):
return 2*x**3 + x - 5
# Appels possibles :
initPort()
# Init. à 9600 bits/s parité : paire
# 8 bits de données 1 bits d’arrêt
initPort(parity=”nulle”)
# Init. à 9600 bits/s parité : nulle
# 8 bits de données 1 bits d’arrêt
5.2. PASSAGE DES ARGUMENTS 43
initPort(2400, ”paire”, 7, 2)
# Init. à 2400 bits/s parité : paire
# 7 bits de données 2 bits d’arrêt
# Exemples d’appel :
print(somme(23)) # 23
print(somme(23, 42, 13)) # 78
# Exemple d’appel :
elements = (2, 4, 6)
print(somme(*elements)) # 12
# Exemples d’appels
## par des paramètres nommés :
print(unDict(a=23, b=42)) # {’a’: 23, ’b’: 42}
## en fournissant un dictionnaire :
mots = {’d’: 85, ’e’: 14, ’f’:9}
print(unDict(**mots)) # {’e’: 14, ’d’: 85, ’f’: 9}
Exemples de portée
x = 99
5.3. ESPACES DE NOMS 45
print(fonc(1)) # 102
x = 99
print(fonc(1)) # 100
x = 99
print(fonc(1)) # 4
46 CHAPITRE 5. FONCTIONS ET ESPACES DE NOMS
Chapitre 6
Modules et packages
6.1 Modules
Définition
å Module : fichier indépendant permettant de scinder un programme en plusieurs scripts.
Ce mécanisme permet d’élaborer efficacement des bibliothèques de fonctions ou de classes.
Avantages des modules :
• réutilisation du code ;
• la documentation et les tests peuvent être intégrés au module ;
• réalisation de services ou de données partagés ;
• partition de l’espace de noms du système.
6.1.2 Exemples
Notion d’« auto-test »
Un module cube_m.py. Remarquez l’utilisation de « l’auto-test » qui permet de tester
le module seul :
def cube(y):
”””Calcule le cube du paramètre <y>.”””
return y**3
# Auto-test ----------------------------------------------------
if __name__ == ”__main__”: # False lors d’un import ==> ignoré
help(cube) # affiche le docstring de la fonction
print(”cube de 9 :”, cube(9)) # cube de 9 : 729
def plotFic(courbes):
dem = open(”_.dem”, ”w”) # fichier réutilisé à chaque tracé
dem.write(”set grid\n”)
plot_data = [”’%s’ with %s” % (c[0], c[1]) for c in courbes]
dem.write(”plot ” + ’,’.join(plot_data))
dem.write(’\npause -1 ”\’Entrée\’ pour continuer”\n’)
dem.write(”reset”)
dem.close()
os.system(”wgnuplot _.dem”)
for i in range(201):
x = 0.1*i - 5.0
y = x**3 - 20*x**2
f.write(”%g %g\n” %(x, y))
y = x**3 - 30*x**2
g.write(”%g %g\n” %(x, y))
y = x**3 - 40*x**2
6.2. BIBLIOTHÈQUE STANDARD 49
if __name__==’__main__’:
def premierMot(ligne): print(ligne.split()[0])
fic = open(”data.dat”)
scanner(fic, premierMot)
import io
chaine = io.StringIO(”un\ndeux xxx\ntrois\n”)
scanner(chaine, premierMot)
50 CHAPITRE 6. MODULES ET PACKAGES
ou
python 6_025.py --help
Options:
-h, --help show this help message and exit
-f FILE, --file=FILE write report to FILE
-q, --quiet don’t print status messages to stdout
d.getcontext().prec = 6
print(d.Decimal(1) / d.Decimal(7)) # 0.142857
d.getcontext().prec = 18
print(d.Decimal(1) / d.Decimal(7)) # 0.142857142857142857
En plus des bibliothèques math et cmath déjà vues, la bibliothèque random propose
plusieurs fonctions de nombres aléatoires.
vendredi_precedent = datetime.date.today()
un_jour = datetime.timedelta(days=1)
while vendredi_precedent.weekday() != calendar.FRIDAY:
vendredi_precedent -= un_jour
print(vendredi_precedent.strftime(”%A, %d-%b-%Y”))
# Friday, 09-Oct-2009
heap = []
for i in range(10):
heapq.heappush(heap, random.randint(2, 9))
print(heap) # [2, 3, 5, 4, 6, 6, 7, 8, 7, 8]
# description du type :
Point = collections.namedtuple(”Point”, ”x y z”)
# on instancie un point :
point = Point(1.2, 2.3, 3.4)
# on l’affiche :
print(”point : [{}, {}, {}]”
.format(point.x, point.y, point.z)) # point : [1.2, 2.3, 3.4]
s = [(’y’, 1), (’b’, 2), (’y’, 3), (’b’, 4), (’r’, 1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
print(d.items())
# dict_items([(’y’, [1, 3]), (’r’, [1]), (’b’, [2, 4])])
s = ’mississippi’
52 CHAPITRE 6. MODULES ET PACKAGES
d = defaultdict(int)
for k in s:
d[k] += 1
print(d.items())
# dict_items([(’i’, 4), (’p’, 2), (’s’, 4), (’m’, 1)])
6.4 Packages
Définition
å Un package est un module contenant d’autres modules. Les modules d’un package
peuvent être des sous-packages, ce qui donne une structure arborescente.
En résumé, un package est simplement un répertoire qui contient des modules et un fichier
__init__.py décrivant l’arborescence du package.
54 CHAPITRE 6. MODULES ET PACKAGES
Chapitre 7
Pour résoudre ce problème et améliorer la lisibilité, on peut utiliser des tuples nommés :
from collection import namedtuple
Par contre, il reste le problème des données invalides, ici un rayon négatif :
cercle = Cercle(11, 60, -8)
Si les cercles doivent changer de caractéristiques, il faut opter pour un type modifiable,
liste ou dictionnaire ce qui ne règle toujours pas le problème des données invalides...
On a donc besoin d’un mécanisme pour empaqueter les données nécessaires pour repré-
senter un cercle et pour empaqueter les méthodes applicables à ce nouveau type de données
(la classe), de telle sorte que seules les opérations valides soient utilisables.
7.2 Terminologie
Le vocabulaire de la POO
Une classe est donc équivalente à un nouveau type de données. On connaît déjà par
exemple int ou str.
Un objet ou une instance est un exemplaire particulier d’une classe. Par exemple ”truc”
est une instance de la classe str.
La plupart des classes encapsulent à la fois les données et les méthodes applicables aux
objets. Par exemple un objet str contient une chaîne de caractères Unicode (les données)
et de nombreuses méthodes comme upper().
On pourrait définir un objet comme une capsule, à savoir un « paquet » contenant des
attributs et des méthodes : objet = [attributs + méthodes]
Beaucoup de classes offrent des caractéristiques supplémentaires comme par exemple la
concaténation des chaînes en utilisant simplement l’opérateur +. Ceci est obtenu grâce aux
méthodes spéciales. Par exemple l’opérateur + est utilisable car on a redéfini la méthode
__add()__.
Les objets ont généralement deux sortes d’attributs : les données nommées simplement
attributs et les fonctions applicables appelées méthodes. Par exemple un objet de la classe
complex possède :
• .imag et .real, ses attributs ;
• beaucoup de méthodes, comme conjugate() ;
• des méthodes spéciales : +, -, /...
Les attributs sont normalement implémentés comme des variables d’instance, particu-
lières à chaque instance d’objet.
Le mécanisme de property permet un accès contrôlé aux données, ce qui permet de les
valider et de les sécuriser.
Un avantage décisif de la POO est qu’une classe Python peut toujours être spécialisée en
une classe fille qui hérite alors de tous les attributs (données et méthodes) de sa supper classe.
Comme tous les attributs peuvent être redéfinis, une méthode de la classe fille et de la classe
mère peut posséder le même nom mais effectuer des traitements différents (surcharge) et
Python s’adaptera dynamiquement, dès l’affectation. En proposant d’utiliser un même nom
de méthode pour plusieurs types d’objets différents, le polymorphisme permet une program-
mation beaucoup plus générique. Le développeur n’a pas à savoir, lorsqu’il programme une
méthode, le type précis de l’objet sur lequel la méthode va s’appliquer. Il lui suffit de savoir
que cet objet implémentera la méthode.
7.3. CLASSES ET INSTANCIATION D’OBJETS 57
Enfin Python supporte également le duck typing : « s’il marche comme un canard et can-
cane comme un canard, alors c’est un canard ! ». Ce qui signifie que Python ne s’intéresse
qu’au comportement des objets. Par exemple un objet fichier peut être créé par open() ou
par une instance de io.StringIO. Les deux approches offrent la même API (interface
de programmation), c’est-à-dire les mêmes méthodes.
Dans cet exemple, C est le nom de la classe (qui commence conventionnellement par une
majuscule), et x est un attribut de classe, local à C.
• Noms non qualifiés (exemple dimension) l’affectation crée ou change le nom dans
la portée locale courante. Ils sont cherchés suivant la règle LGI.
• Noms qualifiés (exemple dimension.hauteur) l’affectation crée ou modifie l’attri-
but dans l’espace de noms de l’objet. Un attribut est cherché dans l’objet, puis dans
toutes les classes dont l’objet dépend (mais pas dans les modules).
L’exemple suivant affiche le dictionnaire lié à la classe C puis la liste des attributs liés à
une instance de C :
class C:
x = 20
7.4 Méthodes
Syntaxe
. Une méthode s’écrit comme une fonction du corps de la classe avec un premier para-
mètre self obligatoire, où self représente l’objet sur lequel la méthode sera appliquée.
Autrement dit self est la référence d’instance.
class C:
x = 23 # x et y : attributs de classe
y = x + 5
def affiche(self): # méthode affiche()
self.z = 42 # attribut d’instance
print(C.y) # dans une méthode, on qualifie un attribut de classe
,
print(self.z) # mais pas un attribut d’instance
7.5.2 L’initialisateur
Lors de l’instanciation d’un objet, la méthode __init__ est automatiquement invoquée.
Elle permet d’effectuer toutes les initialisations nécessaires :
class C:
def __init__(self, n):
self.x = n # initialisation de l’attribut d’instance x
v1 = Vecteur2D(1.2, 2.3)
v2 = Vecteur2D(3.4, 4.5)
60 CHAPITRE 7. LA PROGRAMMATION ORIENTÉE OBJET
class Carre(Rectangle):
def __init__(self, cote=10):
Rectangle.__init__(self, cote, cote)
self.nom = ”carré”
r = Rectangle()
print(r.nom) # ’rectangle’
c = Carre()
print(c.nom) # ’carré’
self.x, self.y = x, y
@property
def distance_origine(self):
return math.hypot(self.x, self.y)
def __str__(self):
return ”({0.x!s}, {0.y!s})”.format(self)
De nouveau, les méthodes renvoyant un simple flottant seront utilisées comme des attri-
buts grâce à property :
class Cercle(Point):
def __init__(self, rayon, x=0, y=0):
super().__init__(x, y)
self.rayon = rayon
@property
def aire(self): return math.pi * (self.rayon ** 2)
@property
def circonference(self): return 2 * math.pi * self.rayon
@property
def distance_bord_origine(self):
62 CHAPITRE 7. LA PROGRAMMATION ORIENTÉE OBJET
@rayon.setter
def rayon(self, rayon):
assert rayon > 0, ”rayon strictement positif”
self.__rayon = rayon
def __str__(self):
return (”{0.__class__.__name__}({0.rayon!s}, {0.x!s}, ”
”{0.y!s})”.format(self))
if __name__ == ”__main__”:
c1 = Cercle(2, 3, 4)
print(c1, c1.aire, c1.circonference)
# Cercle(2, 3, 4) 12.5663706144 12.5663706144
print(c1.distance_bord_origine, c1.rayon) # 3.0 2
c1.rayon = 1 # modification du rayon
print(c1.distance_bord_origine, c1.rayon) # 4.0 1
7.8.1 Composition
Définition
å La composition est la collaboration de plusieurs classes distinctes via une association
(utilise-un) ou une agrégation (a-un).
La classe composite bénéficie de l’ajout de fonctionnalités d’autres classes qui n’ont rien
en commun.
L’implémentation Python utilisée est généralement l’instanciation de classes dans le construc-
teur de la classe composite.
7.8. NOTION DE CONCEPTION ORIENTÉE OBJET 63
Exemple
class Point:
def __init__(self, x, y):
self.px, self.py = x, y
class Segment:
”””Classe composite utilisant la classe distincte Point.”””
def __init__(self, x1, y1, x2, y2):
self.orig = Point(x1, y1) # Segment ”a-un” Point origine,
self.extrem = Point(x2, y2) # et ”a-un” Point extrémité
def __str__(self):
return (”Segment : [({:g}, {:g}), ({:g}, {:g})]”
.format(self.orig.px, self.orig.py,
self.extrem.px, self.extrem.py))
7.8.2 Dérivation
Définition
å La dérivation décrit la création de sous-classes par spécialisation.
On utilise dans ce cas le mécanisme de l’héritage.
L’implémentation Python utilisée est généralement l’appel dans le constructeur de la
classe dérivée du constructeur de la classe parente, soit nommément, soit grâce à l’instruction
super.
Exemple
class Rectangle:
def __init__(self, longueur=30, largeur=15):
self.L, self.l, self.nom = longueur, largeur, ”rectangle”
Ce chapitre présente quelques exemples de techniques avancées dans les trois pa-
radigmes que supporte Python, les programmations procédurale, objet et fonc-
tionnelle.
if __name__ == ”__main__”:
printApi([])
”””
L.append(object) -- append object to end
L.count(value) -> integer -- return number of occurrences of value
L.extend(iterable) -- extend list by appending elements from the
iterable
L.index(value, [start, [stop]]) -> integer -- return first index of
value.
Raises ValueError if the value is not present.
L.insert(index, object) -- insert object before index
L.pop([index]) -> item -- remove and return item at index (default last
).
Raises IndexError if list is empty or index is out of range.
L.remove(value) -- remove first occurrence of value.
Raises ValueError if the value is not present.
queue = [] # initialisation
def enQueue():
queue.append(int(input(”Entrez un entier : ”)))
def deQueue():
if len(queue) == 0:
print(”\nImpossible : la queue est vide !”)
else:
print(”\nElément ’%d’ supprimé” % queue.pop(0))
def afficheQueue():
print(”\nqueue :”, queue)
# import
from queue_FIFO_menu_m import enQueue, deQueue, afficheQueue
menu = ”””
(A)jouter
(V)oir
(S)upprimer
(Q)uitter
while True:
8.1. TECHNIQUES PROCÉDURALES 67
while True:
try:
choix = input(menu).strip()[0].lower()
except:
choix = ’q’
if choix == ’q’:
print(”\nAu revoir !”)
break
CMDs[choix]()
Remarque
3 Son code est très exactement calqué sur sa définition mathématique :
def factorielle(n):
if n == 0: # cas de base : condition terminale
return 1
else # cas récursif
return n*factorielle(n-1)
Dans cette définition, la valeur de n! n’est pas connue tant que l’on n’a pas atteint la
condition terminale (ici n == 0). Le programme empile les appels récursifs jusqu’à atteindre
la condition terminale puis dépile les valeurs.
Ce mécanisme est illustré par la figure 8.1.
if __name__ == ”__main__”:
result = []
for x in quarters():
result.append(x)
if x == 1.0:
break
def quarters(next_quarter=0.0):
while True:
received = (yield next_quarter)
if received is None:
next_quarter += 0.25
else:
next_quarter += received
if __name__ == ”__main__”:
result = []
generator = quarters()
while len(result) < 5:
x = next(generator)
if abs(x - 0.5) < sys.float_info.epsilon:
x = generator.send(1.0) # réinitialise le générarteur
result.append(x)
Utilisation
Les expressions génératrices sont aux générateurs ce que les listes en intension sont aux
fonctions.
# Programme principal
-----------------------------------------------
## création de deux fabriques distinctes
p = creer_plus(23)
q = creer_plus(42)
## utilisation
print(”p(100) =”, p(100))
print(”q(100) =”, q(100))
def uneMethode(self):
print(”normal”)
class CasSpecial(object):
def uneMethode(self):
print(”spécial”)
# fonction
def casQuiConvient(estNormal=True):
”””Fonction fabrique renvoyant une classe.”””
return CasNormal() if estNormal else CasSpecial()
# Programme principal
-----------------------------------------------
une_instance = casQuiConvient()
une_instance.uneMethode() # normal
autre_instance = casQuiConvient(False)
autre_instance.uneMethode() # spécial
8.1. TECHNIQUES PROCÉDURALES 71
fonction = deco(fonction)
#----------------------------------------------------------
# Exemple d’une fonction g multi-décorée�
@f1 @f2 @f3
def g():
pass
# Notation équivalente à : g = f1(f2(f3(g)))
# fonctions
def unDecorateur(f):
def _interne(*args, **kwargs):
print(”Fonction decorée !”)
return f(*args, **kwargs)
return _interne
@unDecorateur
def uneFonction(a, b):
return a + b
”””
Fonction decorée !
3
Fonction decorée !
3
”””
72 CHAPITRE 8. TECHNIQUES AVANCÉES
Quand une classe est créée sans utiliser l’instruction __slot__, ce que nous avons
fait jusqu’à maintenant, Python crée de manière transparente un dictionnaire privé appelé
__dict__ pour chaque instance de la classe, et ce dictionnaire contient les attributs de
l’instance. Voici pourquoi il est possible d’ajouter ou de retirer des attributs d’un objet.
Mais si l’on se contente d’objets sur lesquels nous accédons aux attributs sans en ajouter
ou en ôter, nous pouvons créer des classes sans dictionnaire privé, ce qui économisera de la
mémoire à chaque instanciation. C’est ce qui est réalisé dans l’exemple ci-dessus en définissant
un attribut de classe __slot__ dont la valeur est un tuple formé des noms des attributs.
8.2.2 Functor
En Python un objet fonction ou fonctor est une référence à tout objet « appelable » 1 :
fonction, fonction lambda, méthode, classe. La fonction prédéfinie callable() permet
de tester cette propriété :
>>> def maFonction():
print(’Ceci est ”appelable”’)
>>> callable(maFonction)
True
>>> chaine = ’Ceci est ”appelable”’
>>> callable(chaine)
False
Il est possible de transformer les instances d’une classe en functor si la méthode spéciale
__call__() est définie dans la la classe :
>>> class A:
def __call__(self, un , deux):
return un + deux
>>> a = A()
>>> callable(a)
True
>>> a(1, 6)
7
1. callable en anglais.
8.2. TECHNIQUES OBJETS 73
Python propose un mécanisme pour émuler les attribut privés (le name mangling) : les
identifiants de la classe commencent par deux soulignés (__). Par exemple __ident. Cette
protection reste déclarative et n’offre pas une sécurité absolue.
La solution property
Le principe de l’encapsulation est mis en œuvre par la notion de propriété.
Définition
å Une propriété (property) est un attribut d’instance possédant des fonctionnalités
spéciales.
class C:
def __init__(self):
self._ma_propriete = None
def getx(self):
”””getter.”””
return self._x
def delx(self):
”””deleter.”””
del self._x
# auto-test =========================================================
if __name__ == ’__main__’:
test = C()
test.x = 10 # setter
print(test.x) # getter
print(C.x.__doc__) # documentation
”””
10
Je suis la propriété ’x’.
”””
La seconde, plus simple, utilise la syntaxe des décorateurs. On remarque que la chaîne
de documentation de la property est ici la docstring de la définition de la propriété x :
#!/usr/bin/python3
#-*- coding: utf-8 -*-
# fichier : property2.py
class C:
def __init__(self):
self._x = None
@property
def x(self):
”””Je suis la propriété ’x’.”””
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
# auto-test =========================================================
if __name__ == ’__main__’:
test = C()
test.x = 10 # setter
print(test.x) # getter
print(C.x.__doc__) # documentation
”””
10
Je suis la propriété ’x’.
”””
8.3. TECHNIQUES FONCTIONNELLES 75
Autres exemples :
>>> def makeIncrementor(n):
return lambda x: x+n
>>> f2 = makeIncrementor(2)
>>> f6 = makeIncrementor(6)
>>> print(f2(3), f6(3))
5 9
>>>
>>> L = [lambda x: x**2, lambda x: x**3, lambda x: x**4]
>>> for f in L:
print(f(2), end=” ”)
4 8 16
1. Cf. Wikipedia
2. Idem
76 CHAPITRE 8. TECHNIQUES AVANCÉES
On remarque que map() peut être remplacée par une liste en intension.
La fonction filter() :
filter() construit et renvoie un itérateur sur une liste qui contient tous les éléments
de la séquence initiale répondant au critère :
function(element) == True :
>>> filter(lambda x: x > 0, [1, -2, 3, -4])
[1, 3]
>>>
>>> [x for x in [1, -2, 3, -4] if x > 0]
[1, 3]
On remarque que filter() peut être remplacée par une liste en intension avec un test.
La fonction reduce() :
reduce() est une fonction du module functools. Elle applique de façon cumulative
une fonction de deux arguments aux éléments d’une séquence, de gauche à droite, de façon
à réduire cette séquence à une seule valeur qu’elle renvoie :
>>> def somme(x, y):
print x, ’+’, y
return x + y
Les PFA sont très utiles pour fournir des modèles partiels de widgets, qui ont souvent
de nombreux paramètres. Dans l’exemple suivant, on redéfinit la classe Button en fixant
certains de ses attributs (qui peuvent toujours être surchargés) :
from functools import partial
import tkinter as tk
root = tk.Tk()
# instanciation partielle de classe :
MonBouton = partial(tk.Button, root, fg=’purple’, bg=’green’)
MonBouton(text=”Bouton 1”).pack()
MonBouton(text=”Bouton 2”).pack()
MonBouton(text=”QUITTER”, bg=’red’, fg=’black’,
command=root.quit).pack(fill=tk.X, expand=True)
root.title(”PFA !”)
root.mainloop()
La programmation « OO » graphique
Très utilisée dans les systèmes d’exploitation et dans les applications, les interfaces
graphiques sont programmables en Python.
Parmi les différentes bibliothèques graphiques utilisables dans Python (GTK+,
wxPython, Qt...), la bibliothèque tkinter, issue du langage tcl/Tk est
très employée, car elle est installée de base dans toute les distributions Python.
tkinter facilite la construction d’interfaces graphiques simples. Après avoir
importé la bibliothèque, la méthode consiste à créer, configurer et positionner
les widgets utilisés, à coder les fonctions/méthodes associées aux widgets, puis
d’entrer dans la boucle principale de gestion des événements.
import tkinter
Conception graphique
La conception graphique va nous aider à choisir les bons widgets.
Tout d’abord, il est naturel de distinguer trois zones :
1. la zone supérieure, dédiée à l’affichage ;
2. la zone médiane est une liste alphabétique ordonnée ;
3. la zone inférieure est formée de boutons de gestion de la liste ci-dessus.
Chacune de ces zones est codée par une instance de Frame(), positionnée l’une sous
l’autre grâce au packer, et toutes trois incluses dans une instance de Tk() (cf. conception
Fig. 9.3).
82 CHAPITRE 9. LA PROGRAMMATION « OO » GRAPHIQUE
# class
class Allo_IHM(object):
”””IHM de l’application ’répertoire téléphonique’.”””
def __init__(self, fic):
”””Initialisateur/lanceur de la fenêtre de base”””
self.phoneList = []
self.fic = fic
f = open(fic)
try:
for line in f:
self.phoneList.append(line[: -1].split(’*’))
except: # création du fichier de répertoire
f = open(self.fic, ”w”)
finally:
f.close()
self.phoneList.sort()
9.3. DEUX EXEMPLES 83
self.root = tk.Tk()
self.root.title(”Allo !”)
self.root.config(relief=tk.RAISED, bd=3)
self.makeWidgets()
self.root.mainloop()
def makeWidgets(self):
”Configure et positionne les widgets”
# frame ”saisie” (en haut avec bouton d’effacement)
frameH = tk.Frame(self.root, relief=tk.GROOVE, bd=2)
frameH.pack()
self.scroll = tk.Scrollbar(frameM)
self.select = tk.Listbox(frameM, yscrollcommand=self.scroll.set,
height=6)
self.scroll.config(command=self.select.yview)
self.scroll.pack(side=tk.RIGHT, fill=tk.Y, pady=5)
self.select.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, pady=5)
## remplissage de la Listbox
for i in self.phoneList:
self.select.insert(tk.END, i[0])
self.select.bind(”<Double-Button-1>”, lambda event: self.afficher
(event))
def ajouter(self):
pass
def supprimer(self):
pass
def clear(self):
pass
# auto-test ---------------------------------------------------------
if __name__ == ’__main__’:
app = Allo_IHM(’phones.txt’) # instancie l’IHM
Le code de l’application
On va maintenant utiliser le module de la façon suivante :
– On importe la classe Allo_IHM depuis le module précédent ;
– on crée une classe Allo qui en dérive ;
– son initialisateur appelle l’initialisateur de la classe de base pour hériter de toutes ses
caractéristiques ;
– il reste à surcharger les callbacks.
Enfin, le script instancie l’application.
# imports
import tkinter as tk
from tkPhone_IHM import Allo_IHM
# classes
class Allo(Allo_IHM):
”””Répertoire téléphonique.”””
def __init__(self, fic=’phones.txt’):
”Constructeur de l’IHM.”
Allo_IHM.__init__(self, fic)
def ajouter(self):
# maj de la liste
ajout = [””, ””]
ajout[0] = self.nameEnt.get()
ajout[1] = self.phoneEnt.get()
if (ajout[0] == ””) or (ajout[1] == ””):
return
self.phoneList.append(ajout)
self.phoneList.sort()
# maj de la listebox
self.select.delete(0, tk.END)
for i in self.phoneList:
self.select.insert(tk.END, i[0])
self.clear()
self.nameEnt.focus()
# maj du fichier
f = open(self.fic, ”a”)
f.write(”%s*%s\n” % (ajout[0], ajout[1]))
f.close()
def supprimer(self):
self.clear()
# maj de la liste
retrait = [””, ””]
retrait[0], retrait[1] = self.phoneList[int(self.select.
curselection()[0])]
9.3. DEUX EXEMPLES 85
self.phoneList.remove(retrait)
# maj de la listebox
self.select.delete(0, tk.END)
for i in self.phoneList:
self.select.insert(tk.END, i[0])
# maj du fichier
f = open(self.fic, ”w”)
for i in self.phoneList:
f.write(”%s*%s\n” % (i[0], i[1]))
f.close()
def clear(self):
self.nameEnt.delete(0, tk.END)
self.phoneEnt.delete(0, tk.END)
# programme principal
----------------------------------------------------
app = Allo() # instancie l’application
Méthode
Dans la philosophie du « développement agile », les tests sont écrits en même temps que
le code, voire juste avant. On parle de DDT, Développement Dirigé par les Tests (ou TDD,
Test Driven Developpement).
”””Module de calculs.”””
# fonctions
def moyenne(*args):
”””Renvoie la moyenne.”””
length = len (args)
sum = 0
for arg in args:
sum += arg
return sum/length
# imports
import unittest
import os
import sys
dirName = os.path.dirname(__file__)
if dirName == ’’:
dirName = ’.’
dirName = os.path.realpath(dirName)
upDir = os.path.split(dirName)[0]
if upDir not in sys.path:
sys.path.append(upDir)
# classes
class CalculTest(unittest.TestCase):
def test_moyenne(self):
self.assertEquals(moyenne(1, 2, 3), 2)
self.assertEquals(moyenne(2, 4, 6), 4)
def test_division(self):
self.assertEquals(division(10, 5), 2)
self.assertRaises(ZeroDivisionError, division, 10, 0)
def test_suite():
tests = [unittest.makeSuite(CalculTest)]
return unittest.TestSuite(tests)
if __name__ == ’__main__’:
unittest.main()
10.2 La documentation
Durant la vie d’un projet, on distingue plusieurs types de documentation :
• les documents de spécification (upstream documentation) ;
• les documents techniques attachés au code (mainstream documentation) ;
• les manuels d’utilisation et autres documents de haut niveau (downstream documenta-
tion).
Les documents mainstream évoluent au rythme du code et doivent donc être traités
comme lui : ils doivent pouvoir être lus et manipulés avec un simple éditeur de texte.
Il existe deux outils majeurs pour concevoir des documents pour les applications Python :
le reStructuredText (ou reST) : un format enrichi ;
les doctests : compatibles avec le format reST. Ils permettent de combiner les textes ap-
plicatifs avec les tests.
Section 1
=========
Sous-section
::::::::::::
Sous-sous-section
.................
.. et ceci un commentaire
Section 2
=========
Section 3
=========
---------------
L’utilitaire rst2html, appliqué à ce fichier, produit le fichier de même nom mais avec
l’extention .html (cf. Fig. 10.1).
92 CHAPITRE 10. NOTION DE DÉVELOPPEMENT AGILE
# import
import doctest
# fonctions
def somme(a, b):
”””Renvoie a + b.
>>> somme(2, 2)
4
>>> somme(2, 4)
6
”””
return a+b
if __name__ == ’__main__’:
print(”{:-^40}”.format(” Mode silencieux ”))
doctest.testmod()
print(”Si tout va bien, on a rien vu !”)
input()
print(”{:-^40}”.format(” Mode détaillé ”))
doctest.testmod(verbose=True)
# fonctions
def accentEtrange(texte):
”””Ajoute un accent étrange à un texte.
Exemple :
>>> accentEtrange(texte)
Est-ceu queu tu as rRreugarRrdé la télé hieurRr soirRr ? Il y avait
un théma surRr leus rRramasseuurRrs d’euscarRrgots eun Laponieu,
ils eun baveunt...
def _test():
import doctest
doctest.testmod(verbose=True)
if __name__ == ’__main__’:
_test()
”””
This is the ”example” module.
>>> factorial(5)
120
”””
def factorial(n):
”””Return the factorial of n, an exact integer >= 0.
10.2. LA DOCUMENTATION 95
Factorials of floats are OK, but the float must be an exact integer:
>>> factorial(30.1)
Traceback (most recent call last):
...
ValueError: n must be exact integer
>>> factorial(30.0)
265252859812191058636308480000000
import math
if not n >= 0:
raise ValueError(”n must be >= 0”)
if math.floor(n) != n:
raise ValueError(”n must be exact integer”)
if n+1 == n: # catch a value like 1e300
raise OverflowError(”n too large”)
result = 1
factor = 2
while factor <= n:
result *= factor
96 CHAPITRE 10. NOTION DE DÉVELOPPEMENT AGILE
factor += 1
return result
def _test():
import doctest
doctest.testmod(verbose=True)
if __name__ == ”__main__”:
_test()
print(”OK”)
Exemple : doctest2.py
Source du module 1 .
Le module ‘‘accent‘‘
====================
Les ‘‘r‘‘ sont triplés et les ‘‘e‘‘ épaulés par des ‘‘u‘‘. Cette
technique permet
de se passer de systèmes de traductions complexes pour faire
fonctionner
les logiciels dans certaines régions.
import doctest
doctest.testfile(”doctest2.txt”, verbose=True)
Using ‘‘factorial‘‘
-------------------
>>> factorial(6)
720
import doctest
doctest.testfile(”example.txt”, verbose=True)
Interlude
Le Zen de Python 1
Préfère :
la beauté à la laideur,
l’explicite à l’implicite,
le simple au complexe
et le complexe au compliqué,
le déroulé à l’imbriqué,
l’aéré au compact.
Prends en compte la lisibilité.
Les cas particuliers ne le sont jamais assez pour violer les règles.
Mais, à la pureté, privilégie l’aspect pratique.
Ne passe pas les erreurs sous silence,
... ou bâillonne-les explicitement.
Face à l’ambiguïté, à deviner ne te laisse pas aller.
Sache qu’il ne devrait avoir qu’une et une seule façon de procéder,
même si, de prime abord, elle n’est pas évidente, à moins d’être Néerlandais.
Mieux vaut maintenant que jamais.
Cependant jamais est souvent mieux qu’immédiatement.
Si l’implémentation s’explique difficilement, c’est une mauvaise idée.
Si l’implémentation s’explique aisément, c’est peut-être une bonne idée.
Les espaces de nommage ! Sacrée bonne idée ! Faisons plus de trucs comme ça.
Le Graal de Python 1 !
arthur:
Lancelot ! Lancelot ! Lancelot !
[mégaphone de police]
Lancelooooooooot !
lancelot:
Bloody hell, mais que se passe-t-il donc, mon Roi ?
arthur:
Bevedere, explique-lui !
bevedere:
Nous devons te parler d’un nouveau langage de programmation : Python
lancelot:
Nouveau ? Cela fait bien dix ans qu’il existe, et je ne vois pas en quoi cela va nous
aider à récupérer le Saint-Graal !
bevedere:
Saint-Graal, Saint-Graal...
[soupir]
Tu ne peux pas penser à des activités plus saines que cette quête stupide de temps
en temps ?
arthur:
[sort une massue et assomme Bevedere avec]
Son explication était mal partie de toute manière.
gardes français:
Est-ce que ces messieurs les Anglais peuvent aller s’entretuer plus loin ?
Ne voyez-vous pas que nous sommes concentrés sur notre jeu en ligne ?
arthur:
Ce tunnel sous la Manche, quelle hérésie !
[racle sa gorge]
Lancelot, assieds-toi, et écoute-moi. (et ferme ce laptop, bloody hell !)
1. Cf. [B5] p. 131
103
lancelot:
[rabat l’écran de son laptop]
arthur:
La quête a changé. Tu dois maintenant apprendre le langage Python, et découvrir
pourquoi il est de plus en plus prisé par mes sujets.
lancelot:
Mais...
arthur:
Il n’y a pas de mais !
[menace Lancelot avec sa massue]
Je suis ton Roi. dot slash.
Prends ce livre, et au travail !
gardes français:
Oui, au travail, et en silence !
104 ANNEXE A. INTERLUDE
Annexe B
Position du problème
Nous avons vu que l’ordinateur code toutes les informations qu’il manipule en binaire.
Pour coder les nombres entiers un changement de base suffit, pour les flottants, on utilise une
norme (IEEE 754), mais la situation est plus complexe pour représenter les caractères.
En effet, la grande diversité des langues humaines et de leur représentation nécessite un
codage adapté.
La première idée est de constuire une table qui associe les symboles à représenter à un
nombre (généralement codé sur un octet) :
Symbole ←→ Nombre
La plus célèbre est la table ASCII 1 (cf. Fig.B.1), codée sur 7 bits (soit 128 codes), mais
bien d’autres tables ont été créées (EBCDIC, ISO-8852-1...).
La table Unicode
En Python 3, les chaînes de caractères (le type str()) sont des chaînes Unicode, norme
dans laquelle les identifiants numériques de leurs caractères sont uniques et universels.
Encodage
Après avoir collecté tous les symboles et y avoir associé un nombre, il reste à leur trouver
une représentation binaire.
Pour l’ASCII un seul octet suffisait mais pour représenter les millions de possibilités de
l’Unicode, plusieurs octets par caractère sont nécessaires.
Comme la plupart des textes n’utilisent que la table ASCII ce qui correspond justement
à la partie basse de la table Unicode, l’encodage le plus économique est l’UTF-8.
Pour les codes 0 à 127, l’UTF-8 utilise l’octet de la table ASCII. Pour les caractères
spéciaux (codes 128 à 2047), l’UTF-8 utilise 2 octets. Pour les caractères spéciaux encore
moins courants (codes 2048 à 65535), l’UTF-8 utilise 3 octets, et ainsi de suite 1 .
Symbole ←→ Nombre ←→ Bits
Exemple de l’encodage UTF-8 du caractère Unicode « é » :
é ←→ 233 ←→ C3 A9
Applications pratiques
Les entrées/sorties
Il est important de pouvoir préciser sous quelle forme exacte les données sont attendues
par nos programmes, que ces données soient fournies par l’intermédiaire de frappes au clavier
1. Retour chap. 2 identifiants, p. 8
107
ou par importation depuis une source quelconque. De même, nous devons pouvoir choisir
le format des données que nous exportons vers n’importe quel dispositif périphérique, qu’il
s’agisse d’une imprimante, d’un disque dur, d’un écran...
Pour toutes ces entrées ou sorties de chaînes de caractères, nous devrons donc toujours
considérer qu’il s’agit concrètement de séquences d’octets, et utiliser divers mécanismes pour
convertir ces séquences d’octets en chaînes de caractères, ou vice-versa.
Python met désormais à votre disposition le nouveau type de données bytes, spéci-
fiquement conçu pour traiter les séquences (ou chaînes) d’octets. Les caractères peuvent
bien entendu être encodés en octets, et les octets décodés en caractères (en particulier avec
l’encodage UTF-8 que nous venons de voir) :
>>> chaine = ”Une çédille\n”
>>> of = open(”test.txt”, ”w”) # une chaine de caractères, type str()
>>> of.write(”chaine”)
12
>>> of.close()
>>> of = open(”test.txt”, ”rb”) # une chaine d’octets, type bytes()
>>> octets = of.read()
>>> type(chaine)
<class ’str’>
>>> print(chaine)
Une çédille
>>> len(chaine)
12
>>> type(octets)
<class ’bytes’>
>>> print(octets)
b’Un \xe7\xe9ille\r\b’
>>> len(octets)
13
La logique de Boole
Au 19è siècle, le logicien et mathématicien George Boole restructura complètement la
logique en un système formel. Aujourd’hui, l’algèbre de Boole trouve de nombreuses appli-
cations en informatique et dans la conception des circuits électroniques.
C’est une logique à deux valeurs. Soit B = {0, 1}, l’ensemble de définition, sur lequel on
définit les opérateurs NON, ET et OU.
Les valeurs des variables sont parfois notées False et True. Les opérateurs sont parfois
notés respectivement a, a.b et a + b.
a b a OU b a ET b
0 0 0 0
0 1 1 0
1 0 1 0
1 1 1 1
a b a XOR b a ⇐⇒ b a =⇒ b
0 0 0 1 1
0 1 1 0 1
1 0 1 0 0
1 1 0 1 1
Définition
Définition
å En arithmétique, une base n désigne la valeur dont les puissances successives inter-
viennent dans l’écriture des nombres, ces puissances définissant l’ordre de grandeur de cha-
cune des positions occupées par les chiffres composant tout nombre. Par exemple : 57n =
(5 × n1 ) + (7 × n0 )
Conversion
Définition
å Les changements de base : un nombre dans une base n donnée s’écrit sous la forme
d’addition des puissances successives de cette base 1 .
Exemples
Principe
C’est une application f qui prend en entrée des fichiers de longueur différente, les condense,
et fournit en sortie une séquence binaire de longueur fixe (cf. Fig.E.1) :
où f applique l’ensemble des séquences binaires : {0, 1}∗ = {∅, 0, 1, 10, 11, 100, 101, ...}
sur l’ensemble des séquences binaires de k bits : {0, 1}k = {0...00, 0..01, 0...10, ..., 1...11}.
Cette application doit permettre d’identifier les fichiers en entrée : f (x) = f (y) sera vrai
si et seulement si x = y.
Par contre, à cause de la longueur finie de k, on ne peut pas reconstituer les fichiers :
il existe deux valeurs x et y différentes (fichiers distincts), telles que f (x) = f (y) (même
séquence binaire). On parle alors de collision.
Réalisation pratique
Il faut résoudre deux problèmes :
• diminuer le nombre de collisions en choisissant une séquence binaire assez longue.
Avec, par exemple, k = 512, on obtient 2512 soit environ 10154 cellules disponibles.
• gérer les collisions restantes par un algorithmes approprié.
(a) Stockage sans collision (b) Gestion des collisions par « sondage linéaire »
Par exemple avec des clés de caractères, on utilisera une fonction de hachage ainsi défi-
1
nie :
f : {a, b, c, ..., z}∗ → {0, 1, 2, ..., m − 1}
Soit à stocker les informations suivantes dans un dictionnaire (cf. Fig.E.2) :
lapin 12
renard 2
hérisson 4
ours 1
Exercices corrigés
1. Écrire un programme qui, à partir de la saisie d’un rayon et d’une hauteur, calcule le
volume d’un cône droit.
2. Une boucle while : entrez un prix HT (entrez 0 pour terminer) et affichez sa valeur
TTC.
3. Une autre boucle while : calculez la somme d’une suite de nombres positifs ou nuls.
Comptez combien il y avait de données et combien étaient supérieures à 100.
Un nombre inférieur ou égal à 0 indique la fin de la suite.
4. L’utilisateur donne un entier positif n et le programme affiche PAIR s’il est divisible
par 2 et IMPAIR sinon.
5. L’utilisateur donne un entier positif et le programme annonce combien de fois de suite
cet entier est divisible par 2.
6. L’utilisateur donne un entier supérieur à 1 et le programme affiche, s’il y en a, tous @
ses diviseurs propres sans répétition ainsi que leur nombre. S’il n’y en a pas, il indique
qu’il est premier. Par exemple :
Entrez un entier strictement positif : 12
Diviseurs propres sans répétition de 12 : 2 3 4 6 (soit 4
diviseurs propres)
On n’oubliera pas :
– qu’une semaine comporte 7 jours ;
– qu’une fois en bas, le gardien doit remonter ;
– que le résultat est à exprimer en m.
10. Je suis ligoté sur les rails en gare d’Arras. Écrire un programme qui affiche un tableau
me permettant de connaître l’heure à laquelle je serai déchiqueté par le train parti de
la gare du Nord à 9h (il y a 170 km entre la gare du Nord et Arras).
Le tableau prédira les différentes heures possibles pour toutes les vitesses de 100 km/h
à 300 km/h, par pas de 10 km/h, les résultats étant arrondis à la minute inférieure.
– Écrire une procédure tchacatchac qui reçoit la vitesse du train et qui affiche
l’heure du drame ;
– écrire le programme principal qui affiche le tableau demandé.
@ 11. Un programme principal saisit une chaîne d’ADN valide et une séquence d’ADN va-
lide (« valide » signifie qu’elles ne sont pas vides et sont formées exclusivement d’une
combinaison arbitraire de ”a”, ”t”, ”g” ou ”c”).
Écrire une fonction valide qui renvoie vrai si la saisie est valide, faux sinon.
Écrire une fonction saisie qui effectue une saisie valide et renvoie la valeur saisie
sous forme d’une chaîne de caractères.
Écrire une fonction proportion qui reçoit deux arguments, la chaîne et la séquence
et qui retourne la proportion de séquence dans la chaîne (c’est-à-dire son nombre
d’occurrences).
Le programme principal appelle la fonction saisie pour la chaîne et pour la sé-
quence et affiche le résultat.
Exemple d’affichage :
Il y a 13.33 % de ”ca” dans votre chaîne.
12. Il s’agit d’écrire, d’une part, un programme principal et, d’autre part, une fonction uti-
lisée dans le programme principal.
La fonction listAleaInt(n, a, b) retourne une liste de n entiers aléatoires
dans [a .. b] en utilisant la fonction randint(a, b) du module random.
Dans le programme principal :
– construire la liste en appelant la fonction listAleaInt() ;
– calculer l’index de la case qui contient le minimum ;
– échangez le premier élément du tableau avec son minimum.
117
13. Comme précédemment, il s’agit d’écrire, d’une part, un programme principal et, d’autre
part, une fonction utilisée dans le programme principal.
La fonction listAleaFloat(n) retourne une liste de n flottants aléatoires en
utilisant la fonction random() du module random.
Dans le programme principal :
– Saisir un entier n dans l’intervalle : [2 .. 100] ;
– construire la liste en appelant la fonction listAleaFloat() ;
– afficher l’amplitude du tabeau (écart entre sa plus grande et sa plus petite valeur) ;
– afficher la moyenne du tableau.
14. Fonction renvoyant plusieurs valeurs sous forme d’un tuple.
Écrire une fonction minMaxMoy qui reçoit une liste d’entiers et qui renvoie le mi-
nimum, le maximum et la moyenne de cette liste. Le programme principal appellera
cette fonction avec la liste : [10, 18, 14, 20, 12, 16].
15. Saisir un entier entre 1 et 3999 (pourquoi cette limitation ?). L’afficher en nombre
romain.
16. Améliorer le script précédent en utilisant la fonction zip(). @
17. Un tableau contient n entiers (2 < n < 100) aléatoires tous compris entre 0 et 500. @
Vérifier qu’ils sont tous différents.
18. L’utilisateur donne un entier n entre 2 et 12, le programme donne le nombre de façons
de faire n en lançant deux dés.
19. Même problème que le précédent mais avec n entre 3 et 18 et trois dés.
20. Généralisation des deux questions précédentes. L’utilisateur saisit deux entrées, d’une @@
part le nombre de dés, nbd (que l’on limitera pratiquement à 10) et, d’autre part la
somme, s, comprise entre nbd et 6.nbd. Le programme calcule et affiche le nombre
de façons de faire s avec les nbd dés.
21. Même problème que le précédent mais codé récursivement. @@
22. Nombres parfaits et nombres chanceux.
• On appelle nombre premier tout entier naturel supérieur à 1 qui possède exactement
deux diviseurs, lui-même et l’unité.
• On appelle diviseur propre de n, un diviseur quelconque de n, n exclu.
• Un entier naturel est dit parfait s’il est égal à la somme de tous ses diviseurs propres.
• Les nombres a tels que : (a+n+n2 ) est premier pour tout n tel que 0 ≤ n < (a−1),
sont appelés nombres chanceux.
Écrire un module (parfait_chanceux_m.py) définissant quatre fonctions : som-
Div, estParfait, estPremier, estChanceux et un auto-test :
• la fonction somDiv retourne la somme des diviseurs propres de son argument ;
• les trois autres fonctions vérifient la propriété donnée par leur définition et retourne
un booléen. Plus précisément, si par exemple la fonction estPremier vérifie que
son argument est premier, elle retourne True, sinon elle retourne False.
La partie de test doit comporter quatre appels à la fonction verif permettant de tester
somDiv(12), estParfait(6), estPremier(31) et estChanceux(11).
Puis écrire le programme principal (parfait_chanceux.py) qui comporte :
118 ANNEXE F. EXERCICES CORRIGÉS
# imports
from math import pi
volume = (pi*rayon*rayon*hauteur)/3.0
print(”Volume du cône =”, volume, ”m3”)
if n%2 == 0:
print(n, ”est pair.”)
else:
print(n, ”est impair.”)
cpt = 0
while n%2 == 0:
n /= 2
cpt += 1
if not cpt:
print(”aucun ! Il est premier.”)
else:
print(”(soit”, cpt, ”diviseurs propres)”)
# fonction
def fact(n):
r = 1
for i in range(1, n+1):
r *= i
return r
exp = 0.0
for i in range(n):
exp = exp + 1.0/fact(i)
# fonction
def hauteurParcourue(nb, h):
print(”Pour {:d} marches de {:d} cm, il parcourt {:.2f} m par
semaine.”.format(nb, h, nb*h*2*5*7/100.0))
hauteurParcourue(nbMarches, hauteurMarche)
# fonction
def permisSup(p, c, v, a):
pointsPerdus = p + 3*c + 5*v + 10*a
nbrePermis = pointsPerdus/100.0
return 200*nbrePermis
# fonction
def tchacatchac(v):
”””Affiche l’heure du drame.”””
heure = 9 + int(170/v)
minute = (60 * 170 / v) % 60
print(”A”, v, ”km/h, je me fais déchiqueter à”, heure, ”h”, minute,
”min.”)
# fonctions
def valide(seq):
”””Retourne vrai si la séquence est valide, faux sinon.”””
ret = any(seq)
for c in seq:
ret = ret and c in ”atgc”
return ret
def saisie(ch):
s = input(”{:s} : ”.format(ch))
while not valide(s):
print(”’{:s}’ ne peut contenir que les chaînons ’a’, ’t’, ’g’ et
’c’ et”
” ne doit pas être vide”.format(ch))
s = input(”{:s} : ”.format(ch))
return s
# imports
from random import seed, randint
# fonction
def listAleaInt(n, a, b):
”””Retourne une liste de <n> entiers aléatoires dans [<a> .. <b>].
”””
return [randint(a, b) for i in range(n)]
# imports
from random import seed, random
# fonctions
def listAleaFloat(n):
”Retourne une liste de <n> flottants aléatoires”
return [random() for i in range(n)]
# fonction
def minMaxMoy(liste):
”””Renvoie le min, le max et la moyenne de la liste.”””
min, max, som = liste[0], liste[0], float(liste[0])
for i in liste[1:]:
if i < min:
min = i
if i > max:
max = i
som += i
return (min, max, som/len(liste))
s = ”” # Chaîne résultante
if n >= 900:
s += ”CM”
123
n -= 900
if n >= 500:
s += ”D”
n -= 500
if n >= 400:
s += ”CD”
n -= 400
if n >= 90:
s += ”XC”
n -= 90
if n >= 50:
s += ”L”
n -= 50
if n >= 40:
s += ”XL”
n -= 40
if n >= 9:
s += ”IX”
n -= 9
if n >= 5:
s += ”V”
n -= 5
if n >= 4:
s += ”IV”
n -= 4
while n >= 1:
s += ”I”
n -= 1
# globales
code = zip(
[1000,900 ,500,400 ,100,90 ,50 ,40 ,10 ,9 ,5 ,4 ,1],
[”M” ,”CM”,”D”,”CD”,”C”,”XC”,”L”,”XL”,”X”,”IX”,”V”,”IV”,”I”]
)
# fonction
124 ANNEXE F. EXERCICES CORRIGÉS
def decToRoman(num):
res = []
for d, r in code:
while num >= d:
res.append(r)
num -= d
return ’’.join(res)
# imports
from random import seed, randint
# fonction
def listAleaInt(n, a, b):
”””Retourne une liste de <n> entiers aléatoires entre <a> et <b>.”””
return [randint(a, b) for i in range(n)]
# construction de la liste
seed() # initialise le générateur de nombres aléatoires
t = listAleaInt(n, 0, 500)
# Sont-ils différents ?
tousDiff = True
i = 0
while tousDiff and i < (n-1):
j = i + 1
while tousDiff and j < n:
if t[i] == t[j]:
tousDiff = False
else:
j += 1
i += 1
print(”\n”, t, end=’ ’)
if tousDiff:
print(”: tous les éléments sont distincts.”)
else:
print(”: au moins une valeur est répétée.”)
s = 0
125
s = 0
for i in range(1, 7):
for j in range(1, 7):
for k in range(1, 7):
if i+j+k == n:
s += 1
# globale
MAX = 8
if s == nbd or s == 6*nbd:
cpt = 1 # 1 seule solution
else:
I = [1]*nbd # initialise une liste de <nbd> dés
cpt, j = 0, 0
while j < nbd:
som = sum([I[k] for k in range(nbd)])
if som == s:
cpt += 1 # compteur de bonnes solutions
if som == 6*nbd:
break
j = 0
if I[j] < 6:
I[j] += 1
else:
while I[j] == 6:
126 ANNEXE F. EXERCICES CORRIGÉS
I[j] = 1
j += 1
I[j] += 1
# globale
MAX = 8
# fonction
def calcul(d, n):
”””Calcul récursif du nombre de façons de faire <n> avec <d> dés.”””
resultat, debut = 0, 1
if (d == 1) or (n == d) or (n == 6*d): # conditions terminales
return 1
else: # sinon appels récursifs
if n > 6*(d-1): # optimisation importante
debut = n - 6*(d-1)
# classes
class Rectangle:
”””classe des rectangles.”””
def __init__(self, longueur=30, largeur=15):
”””Constructeur avec valeurs par défaut.”””
self.lon = longueur
self.lar = largeur
self.nom = ”rectangle”
def surface(self):
”””Calcule la surface d’un rectangle.”””
return self.lon*self.lar
def __str__(self):
127
class Carre(Rectangle):
”””classe des carrés (hérite de Rectangle).”””
def __init__(self, cote=10):
”””Constructeur avec valeur par défaut”””
Rectangle.__init__(self, cote, cote)
self.nom = ”carré” # surchage d’attribut d’instance
# Auto-test ---------------------------------------------------------
if __name__ == ’__main__’:
r = Rectangle(12, 8)
print r
c = Carre()
print c
F
128 ANNEXE F. EXERCICES CORRIGÉS
Annexe G
Ressources
Webographie
• Les sites généraux :
www.python.org
pypi.python.org/pypi
www.pythonxy.com/download.php
rgruet.free.fr
• Les EDI spécialisés :
www.wingware.com/downloads/wingide-101
eric-ide.python-projects.org/eric4-download.html
www.eclipse.org/downloads/
www.scintilla.org/SciTEDownload.html
• Les outils :
sourceforge.net/projects/gnuplot/files/
• L’abrégé Python 3.1 en un recto/verso :
perso.limsi.fr/pointal/python :abrege
• Le lien des liens :
perso.limsi.fr/pointal/liens :langage_python
130 ANNEXE G. RESSOURCES
Bibliographie
131
132 BIBLIOGRAPHIE
Annexe H
Glossaire
Lexique bilingue
>>> Invite Python par défaut dans un shell interactif. Souvent utilisée dans les exemples
de code extraits de sessions de l’interpréteur Python.
... Invite Python par défaut dans un shell interactif, utilisée lorsqu’il faut entrer le code d’un
bloc indenté ou à l’intérieur d’une paire de parenthèses, crochets ou accolades.
2to3 Un outil qui essaye de convertir le code Python 2.x en code Python 3.x en gérant la
plupart des incompatibilités qu’il peut détecter.
2to3 est disponible dans la bibliothèque standard lib2to2 ; un point d’entrée au-
tonome est Tool/scipts/2to3. Voir 2to3 – Automated Python 2 to 3 code
translation.
abstract base class ABC (classe de base abstraite) Complète le duck-typing en fournissant
un moyen de définir des interfaces alors que d’autres techniques (comme hasattt())
sont plus lourdes. Python fournit de base plusieurs ABC pour les structures de données
(module collections), les nombres (module numbers) et les flux (module io).
Vous pouvez créer votre propre ABC en utilisant le module abc.
argument (argument) Valeur passée à une fonction ou une méthode, affectée à une variable
nommée locale au corps de la fonction. Une fonction ou une méthode peut avoir à la
fois des arguments par position et avec des valeurs par défaut. Ces arguments peuvent
être de multiplicité variable : * accepte ou fournit plusieurs arguments par position
dans une liste, tandis que ** joue le même rôle en utilisant les valeurs par défaut dans
un dictionnaire.
On peut passer toute expression dans la liste d’arguments, et la valeur évaluée est trans-
mise à la variable locale.
attribute (attribut) Valeur associée à un objet référencé par un nom et une expression poin-
tée. Par exemple, l’attribut a d’un objet o peut être référencé o.a.
BDFL Benevolent Dictator For Life, c’est-à-dire Guido van Rossum, le créateur de Python.
bytecode (bytecode ou langage intermédiaire) Le code source Python est compilé en byte-
code, représentation interne d’un programme Python dans l’interpréteur. Le bytecode
est également rangé dans des fichiers .pyc et .pyo, ainsi l’exécution d’un même
fichier est plus rapide les fois ultérieures (la compilation du source en bytecode peut
être évitée). On dit que le bytecode tourne sur une machine virtuelle qui, essentiel-
lement, se réduit à une collection d’appels des routines correspondant à chaque code
du bytecode.
class (classe) Modèle permettant de créer ses propres objets. Les définitions de classes
contiennent normalement des définitions de méthodes qui opèrent sur les instances
de classes.
134 ANNEXE H. GLOSSAIRE
coercion (coercition ou transtypage) Conversion implicite d’une instance d’un type dans un
autre type dans une opération concernant deux arguments de types compatibles. Par
exemple, int(3.15) convertit le nombre flottant 3.15 en l’entier 3, mais dans
3+4.5, chaque argument est d’un type différent (l’un int et l’autre float) et tous
deux doivent être convertis dans le même type avant d’être additionnés, sinon une
exception TypeError sera lancée. Sans coercition, tous les arguments, même de
types compatibles, doivent être normalisés à la même valeur par le programmeur, par
exemple, float(3)+4.5 au lieu de simplement 3+4.5.
complex number (nombre complexe) Une extension du système familier des nombres réels
dans laquelle tous les nombres sont exprimés comme la somme d’une partie réelle
et une partie imaginaire. Les nombres imaginaires sont des multiples réels de l’unité
imaginaire (la racine carrée de -1), souvent écrite i par les mathématiciens et j par
les ingénieurs. Python a un traitement incorporé des nombres complexes, qui sont
écrits avec cette deuxième notation ; la partie imaginaire est écrite avec un suffixe
j, par exemple 3+1j. Pour avoir accès aux équivalents complexes des éléments du
module math utilisez le module cmath. L’utilisation des nombres complexes est une
possibilité mathématique assez avancée. Si vous n’êtes pas certain d’en avoir besoin
vous pouvez les ignorer sans risque.
context manager (gestionnaire de contexte) Objet qui contrôle l’environnement indiqué par
l’instruction with et qui définit les méthodes __enter__() et __exit__().
Voir la PEP 343.
CPython (Python classique) Implémentation canonique du langage de programmation Py-
thon. Le terme CPython est utilisé dans les cas où il est nécessaire de distinguer cette
implémentation d’autres comme Jython ou IronPython.
decorator (décorateur) Fonction retournant une autre fonction habituellement appliquée
comme une transformation utilisant la syntaxe @wrapper.
classmethod() et staticmethod() sont des exemples classiques de décora-
teurs.
Les deux définitions de fonctions suivantes sont sémantiquement équivalentes :
def f(...):
...
f = staticmethod(f)
@staticmethod
def f(...):
...
Un concept identique existe pour les classes mais est moins utilisé. Voir la documen-
tation function definition et class definition pour plus de détails sur les décorateurs.
descriptor (descripteur) Tout objet qui définit les méthodes __get__(), __set__()
ou __delete__(). Lorsqu’un attribut d’une classe est un descripteur, un compor-
tement spécifique est déclenché lors de la consultation de l’attribut. Normalement,
écrire a.b consulte l’objet b dans le dictionnaire de la classe de a, mais si b est un
descripteur, la méthode __get__() est appelée. Comprendre les descripteurs est
fondamental pour la compréhension profonde de Python, car ils sont à la base de
nombreuses caractéristiques, comme les fonctions, les méthodes, les propriétés, les
méthodes de classe, les méthodes statiques et les références aux super-classes.
Pour plus d’informations sur les méthodes des descripteurs, voir Implementing Des-
criptors.
135
dictionary (dictionnaire) Une table associative, dans laquelle des clés arbitraires sont as-
sociées à des valeurs. L’utilisation des objets dict ressemble beaucoup à celle des
objets list, mais les clés peuvent être n’importe quels objets ayant une fonction
__hash__(), non seulement des entiers. Ces tables sont appelées hash en Perl.
docstring (chaîne de documentation) Chaîne littérale apparaissant comme première ex-
pression d’une classe, d’une fonction ou d’un module. Bien qu’ignorée à l’exécution,
elle est reconnue par le compilateur et incluse dans l’attribut __doc__ de la classe, de
la fonction ou du module qui la contient. Depuis qu’elle est disponible via l’instrospection,
c’est l’endroit canonique pour documenter un objet.
duck-typing (typage « comme un canard ») Style de programmation pythonique dans lequel
on détermine le type d’un objet par inspection de ses méthodes et attributs plutôt que
par des relations explicites à des types (« s’il ressemble à un canard et fait coin-coin
comme un canard alors ce doit être un canard »). En mettant l’accent sur des interfaces
plutôt que sur des types spécifiques on améliore la flexibilité du code en permettant
la substitution polymorphe. Le duck-typing évite les tests qui utilisent type() ou
isinstance() (notez cependant que le duck-typing doit être complété par l’emploi
des classes de base abstraites). À la place, il emploie des tests comme hasattr()
et le style de programmation EAFP.
EAFP (Easier to ask for forgiveness than permission, ou « plus facile de demander pardon
que la permission »). Ce style courant de programmation en Python consiste à supposer
l’existence des clés et des attributs nécessaires à l’exécution d’un code et à attraper les
exceptions qui se produisent lorsque de telles hypothèses se révèlent fausses. C’est un
style propre et rapide, caractérisé par la présence de nombreuses instructions try et
except. Cette technique contraste avec le style LBYL, courant dans d’autres langages
comme le C.
expression (expression) Fragment de syntaxe qui peut être évalué. Autrement dit, une ex-
pression est une accumulation d’éléments d’expression comme des littéraux, des noms,
des accès aux attributs, des opérateurs ou des appels à des fonctions retournant une
valeur. À l’inverse de beaucoup d’autres langages, toutes les constructions de Python
ne sont pas des expressions. Les instructions ne peuvent pas être utilisées comme des
expressions (par exemple if). Les affectations sont aussi des instructions, pas des
expressions.
extension module (module d’extention) Module écrit en C ou en C++, utilisant l’API C de
Python, qui interagit avec le cœur du langage et avec le code de l’utilisateur.
finder Objet qui essaye de trouver le loader (chargeur) d’un module. Il doit implémenter
une méthode nommée find_module(). Voir la PEP 302 pour des détails et im-
portlib.abc.Finder pour une classe de base abstraite.
floor division (division entière) Division mathématique qui laisse tomber le reste. L’opérateur
de division entière est //. Par exemple, l’expression 11//4 est évaluée à 2, par op-
position à la division flottante qui retourne 2.75.
function (fonction) Suite d’instructions qui retourne une valeur à l’appelant. On peut lui
passer zéro ou plusieurs arguments qui peuvent être utilisés dans le corps de la fonction.
Voir aussi argument et method.
__future__ Un pseudo-module que les programmeurs peuvent utiliser pour permettre les
nouvelles fonctionnalités du langage qui ne sont pas compatibles avec l’interpréteur
couramment employé.
136 ANNEXE H. GLOSSAIRE
de Python. Excellent pour les débutants, il peut aussi servir d’exemple pas trop sophis-
tiqué pour tous ceux qui doivent implémenter une application avec interface utilisateur
graphique multi-plate-forme.
immutable (immuable) Un objet avec une valeur fixe. Par exemple, les nombres, les chaînes,
les tuples. De tels objets ne peuvent pas être altérés ; pour changer de valeur un nouvel
objet doit être créé. Les objets immuables jouent un rôle important aux endroits où
une valeurs de hash constantes est requise, par exemple pour les clés des dictionnaires.
importer Objet qui à la fois trouve et charge un module. C’est à la fois un objet finder et un
objet loader.
interactive (interactif) Python possède un interpréteur interactif, ce qui signifie que vous
pouvez essayer vos idées et voir immédiatement les résultats. Il suffit de lancer py-
thon sans argument (éventuellement en le sélectionnant dans un certain menu prin-
cipal de votre ordinateur). C’est vraiment un moyen puissant pour tester les idées nou-
velles ou pour inspecter les modules et les paquetages (pensez à help(x)).
interpreted (interprété) Python est un langage interprété, par opposition aux langages com-
pilés, bien que cette distinction puisse être floue à cause de la présence du compilateur
de bytecode. Cela signifie que les fichiers source peuvent être directement exécutés
sans avoir besoin de créer préalablement un fichier binaire exécuté ensuite. Typique-
ment, les langages interprétés ont un cycle de développement et de mise au point plus
court que les langages compilés mais leurs programmes s’exécutent plus lentement.
Voir aussi interactive.
iterable Un objet conteneur capable de renvoyer ses membres un par un. Des exemples
d’iterable sont les types séquences (comme les list, les str, et les tuple) et
quelques types qui ne sont pas des séquences, comme les objets dict, les objets
file et les objets de n’importe quelle classe que vous définissez avec une méthode
__iter__() ou une méthode __getitem__(). Les iterables peuvent être uti-
lisés dans les boucles for et dans beaucoup d’autres endroits où une séquence est
requise (zip(), map(), ...). Lorsqu’un objet iterable est passé comme argument à
la fonction incorporée iter() il renvoie un itérateur. Cet itérateur est un bon moyen
pour effectuer un parcours d’un ensemble de valeurs. Lorsqu’on utilise des iterables,
il n’est généralement pas nécesaire d’appeler la fonction iter() ni de manipuler di-
rectement les valeurs en question. L’instruction for fait cela automatiquement pour
vous, en créant une variable temporaire sans nom pour gérer l’itérateur pendant la
durée de l’itération. Voir aussi iterator, sequence, et generator.
iterator (itérateur) Un objet représentant un flot de données. Des appels répétés à la mé-
thode __next__() de l’itérateur (ou à la fonction de base next()) renvoient des
éléments successifs du flot. Lorsqu’il n’y a plus de données disponibles dans le flot, une
exception StopIteration est lancée. À ce moment-là, l’objet itérateur est épuisé
et tout appel ultérieur de la méthode next() ne fait que lancer encore une excep-
tion StopIteration. Les itérateurs doivent avoir une méthode __iter__()
qui renvoie l’objet itérateur lui-même. Ainsi un itérateur est itératif et peut être utilisé
dans beaucoup d’endroits où les iterables sont acceptés ; une exception notable est un
code qui tenterait des itérations multiples. Un objet conteneur (comme un objet list)
produit un nouvel itérateur à chaque fois qu’il est passé à la fonction iter() ou bien
utilisé dans une boucle for. Si on fait cela avec un itérateur on ne récupérera que
le même itérateur épuisé utilisé dans le parcours précédent, ce qui fera apparaître le
conteneur comme s’il était vide.
138 ANNEXE H. GLOSSAIRE
keyword argument (argument avec valeur par défaut) Argument précédé par varia-
ble_name= dans l’appel. Le nom de la variable désigne le nom local dans la fonction
auquel la valeur est affectée. ** est utilisé pour accepter ou passer un dictionnaire
d’arguments avec ses valeurs. Voir argument.
lambda Fonction anonyme en ligne ne comprenant qu’une unique expression évaluée à
l’appel. Syntaxe de création d’une fonction lambda :
lambda[arguments]: expression
LBYL (Look before you leap ou « regarder avant d’y aller »). Ce style de code teste explicite-
ment les pré-conditions avant d’effectuer un appel ou une recherche. Ce style s’oppose
à l’approche EAFP et est caractérisé par la présence de nombreuses instructions if.
list (liste) Séquence Python de base. En dépit de son nom, elle ressemble plus au tableau
d’autres langages qu’à une liste chaînée puisque l’accès à ses éléments est en O(1).
list comprehension (liste en intention) Une manière compacte d’effectuer un traitement sur
un sous-ensemble d’éléments d’une séquence en renvoyant une liste avec les résultats.
Par exemple :
result = [”0x%02x” % x for x in range(256) if x % 2 == 0]
engendre une liste de chaînes contenant les écritures hexadécimales des nombres im-
pairs de l’intervalle de 0 à 255. La clause if est facultative. Si elle est omise, tous
les éléments de l’intervalle range(256) seront traités.
loader (chargeur) Objet qui charge un module. Il doit posséder une méthode load_mo-
dule(). un loader est typiquement fournit par un finder. Voir la PEP 302 pour les
détails et voir importlib.abc.Loader pour une classe de base abstraite.
mapping (liste associative) Un objet conteneur (comme dict) qui supporte les recherches
par des clés arbitraires en utilisant la méthode spéciale __getitem__().
metaclass La classe d’une classe. La définition d’une classe crée un nom de classe, un dic-
tionnaire et une liste de classes de base. La métaclasse est responsable de la création
de la classe à partir de ces trois éléments. Beaucoup de langages de programmation
orientés objets fournissent une implémentation par défaut. Une originalité de Python
est qu’il est possible de créer des métaclasses personnalisées. Beaucoup d’utilisateurs
n’auront jamais besoin de cela mais, lorsque le besoin apparaît, les métaclasses four-
nissent des solutions puissantes et élégantes. Elles sont utilisées pour enregistrer les
accès aux attributs, pour ajouter des treads sécurisés, pour détecter la création d’objet,
pour implémenter des singletons et pour bien d’autres tâches.
Plus d’informations peuvent être trouvées dans Customizing class creation.
method (méthode) Fonction définie dans le corps d’une classe. Appelée comme un attri-
but d’une instance de classe, la méthode prend l’instance d’objet en tant que premier
argument (habituellement nommé self). Voir function et nested scope.
mutable (modifiable) Les objets modifiables peuvent changer leur valeur tout en conservant
leur id(). Voir aussi immutable.
named tuple (tuple nommé) Toute classe de pseudo-tuples dont les éléments indexables
sont également accessibles par des attributs nommés (par exemple time.localti-
me() retourne un objet pseudo-tuple où l’année est accessible soit par un index comme
t[0] soit par un attribut nommé comme t.tm_year.
Un tuple nommé peut être un type de base comme time.struct_time ou il peut
139
être créé par une définition de classe ordinaire. Un tuple nommé peut aussi être créé
par la fonction fabrique collections.nametuple(). Cette dernière approche
fournit automatiquement des caractéristiques supplémentaires comme une représen-
tation auto-documentée, par exemple :
>>> Employee(name=’jones’, title=’programmer’)
namespace (espace de noms) L’endroit où une variable est conservée. Les espaces de noms
sont implémentés comme des dictionnaires. Il y a des espace de noms locaux, globaux
et intégrés et également imbriqués dans les objets. Les espaces de noms contribuent à
la modularité en prévenant les conflits de noms. Par exemple, les fonctions __buil-
tin__.open() et os.open() se distinguent par leurs espaces de noms. Les es-
paces de noms contribuent aussi à la lisibilité et la maintenablité en clarifiant quel
module implémente une fonction. Par exemple, en écrivant random.seed() ou
itertools.izip() on rend évident que ces fonctions sont implémentées dans
les modules random et itertools respectivement.
nested scope (portée imbriquée) La possibilité de faire référence à une variable d’une défi-
nition englobante. Par exemple, une fonction définie à l’intérieur d’une autre fonction
peut faire référence à une variable de la fonction extérieure. Notez que le portées im-
briquées fonctionnent uniquement pour la référence aux variables et non pour leur
affectation, qui concerne toujours la portée imbriquée. Les variables locales sont lues
et écrites dans la portée la plus intérieure ; les variables globales sont lues et écrites
dans l’espace de noms global. Linstruction nonlocal permet d’écrire dans la portée
globale.
new-style class (style de classe nouveau) Vieille dénomination pour le style de program-
mation de classe actuellement utilisé. Dans les versions précédentes de Python, seul
le style de classe nouveau pouvait bénéficier des nouvelles caractéristiques de Python,
comme __slots__, les descripteurs, les propriétés, __getattribute__(), les
méthodes de classe et les méthodes statiques.
object (objet) Toute donnée comprenant un état (attribut ou valeur) et un comportement
défini (méthodes). Également la classe de base ultime du new-style class.
positional argument (argument de position) Arguments affectés aux noms locaux internes
à une fonction ou à une méthode, determinés par l’ordre donné dans l’appel. La syntaxe
* accepte plusieurs arguments de position ou fournit une liste de plusieurs arguments
à une fonction. Voir argument.
property (propriété) Attribut d’instance permettant d’implémenter les principes de l’encap-
sulation.
Python3000 Surnom de la version 3 de Python (forgé il y a longtemps, quand la version 3
était un projet lointain). Aussi abrégé « Py3k ».
Pythonic (pythonique) Idée ou fragment de code plus proche des idiomes du langage Py-
thon que des concepts fréquemment utlisés dans d’autres langages. par exemple, un
idiome fréquent en Python est de boucler sur les éléments d’un iterable en utilisant
l’instruction for. Beaucoup d’autres langages n’ont pas ce type de construction et
donc les utilisateurs non familiers avec Python utilisent parfois un compteur numé-
rique :
for i in range(len(food)):
print(food[i])
140 ANNEXE H. GLOSSAIRE
reference count (nombre de références) Nombre de références d’un objet. Quand le nombre
de références d’un objet tombe à zéro, l’objet est désalloué. Le comptage de réfé-
rences n’est généralement pas visible dans le code Python, mais c’est un élément clé de
l’implémentation de CPython. Le module sys définit la fonction getrefcount()
que les programmeurs peuvent appeler pour récupérer le nombre de références d’un
objet donné.
__slots__ Une déclaration à l’intérieur d’une classe de style nouveau qui économise la mé-
moire en pré-déclarant l’espace pour les attributs et en éliminant en conséquence les
dictionnaires d’instance. Bien que populaire, cette technique est quelque peu difficile
à mettre en place et doit être réservée aux rares cas où il y a un nombre important
d’instances dans une application où la mémoire est réduite.
sequence (séquence) Un iterable qui offre un accès efficace aux éléments en utilisant des
index entiers et les méthodes spéciales __getitem__() et __len__(). Des types
séquences incorporés sont list, str, tuple et unicode. Notez que le type dict
comporte aussi les méthodes __getitem__() et __len__(), mais est considéré
comme une table associative plutôt que comme une séquence car la recherche se fait
à l’aide de clés arbitraires immuables au lieu d’index.
slice (tranche) Objet contenant normalement une partie d’une séquence. Une tranche est
créée par une notation indexée utilisant des « : » entre les index quand plusieurs sont
donnés, comme dans variable_name[1:3:5]. La notation crochet utilise les
objets slice de façon interne.
special method (méthode spéciale) méthode appelée implicitement par Python pour exé-
cuter une certaine opération sur un type, par exemple une addition. Ces méthodes
ont des noms commençant et finissant par deux caractères soulignés. Les méthodes
spéciales sont documentées dans Special method names.
statement (instruction) Une instruction est une partie d’une suite, d’un « bloc » de code. Une
instruction est soit une expression soit une ou plusieurs constructions utilisant un mot
clé comme if, while ou for.
triple-quoted string (chaîne multi-ligne) Une chaîne délimitée par trois guillemets (”) ou
trois apostrophes (’). Bien qu’elles ne fournissent pas de fonctionnalités différentes de
celles des chaînes simplement délimitées, elles sont utiles pour nombre de raisons. Elles
permettent d’inclure des guillemets ou des apostrophes non protégés et elles peuvent
s’étendre sur plusieurs lignes sans utiliser de caractère de continuation, et sont donc
spécialement utiles pour rédiger des chaînes de documentation.
type (type) Le type d’un objet Python détermine de quelle sorte d’objet il s’agit ; chaque objet
possède un type. Le type d’un objet est accessible grâce à son attribut __class__
ou peut être retourné par la fonction type(obj).
view (vue) Les objets retournés par dict.keys(), dict.values() et dict.items()
sont appelés des dictionary views. ce sont des « séquences paresseuses 1 » qui laisse-
ront voir les modifications du dictionnaire sous-jacent. Pour forcer le dictionary view à
être une liste complète, utiliser list(dictview). Voir Dictionary wiew objects.
1. L’évaluation paresseuse est une technique de programmation où le programme n’exécute pas de code
avant que les résultats de ce code ne soient réellement nécessaires. Le terme paresseux (en anglais lazzy eva-
luation) étant connoté négativement en français on parle aussi d’évaluation retardée.
141