Python 1
Python 1
Python 1
n
)
0k<n
. Vrifier
numriquement (modules cmath) que
0k<n
e
2ik
n
= 0
0k<n
e
2ik
n
= 1
Exercice 17. Dveloppement limit de log (1 x) , x < 1
70 Chapitre 3. Structures de contrle
On rappelle que le dveloppement en srie entire de log (1 x) a pour rayon de convergence
r = 1 et
log (1 x) =
k1
x
k
k
(1) Calculer la somme des 100 premiers termes de la srie, pour x = 0.5. Comparer avec log
(
1
2
)
(2) Calculer la somme des termes de la srie jusqu ce que la somme soit (numriquement)
stationnaire. Combien de termes faut-il ?
Exercice 18. (Exercice faire en Python 2 seulement. En Python 3 donne lieu une boucle
infinie car il ny a pas de plus grand entier)
Utiliser une boucle while, la fonction type() pour dterminer la valeur, M, du plus grand entier,
en Python . Montrer que n N : M + 1 = 2
n
. Calculer M
2
Exercice 19. Trouver n N tel que 1.0 2
n
= 0.0 et 1.0 2
n+1
= 0.0
Exercice 20. Produit scalaire
(1) On reprsente les vecteurs de R
n
par des listes Python de rels. crire une boucle qui calcule
le produit scalaire (X, Y ) =
1in
x
i
y
i
.
(2) crire la mme boucle en utilisant les list comprhension. On peut crire le produit scalaire
sans voir apparatre un seul indice.
Exercice 21. Produit matrice vecteur.
La liste X=[1,1,1] reprsente le vecteur
1
1
1
1 2 3
0 1 0
1 1 0
.
(1) crire une boucle qui calcule le produit matriciel Y = A.X et le stocke dans une liste Y.
(2) crire la mme boucle en utilisant les list comprhension. On peut crire le produit matrice-
vecteur sans voir apparatre un seul indice.
Exercice 22. Matrices. On dcide de reprsenter une matrice A R
m,n
par une liste A de m listes
n lments. De sorte quun lment a
i,j
est stock en A[i][j]
Pour deux matrices A R
m,n
et B R
n,p
, le produit A B est dfinit par A B R
m,p
et,
pour 1 i m, 1 j p
c
i,j
=
1kn
a
i,k
b
k,j
(1) crire une fonction zeros(m,n) qui renvoie une liste de m listes de taille n remplies de 0.
Cette liste de listes reprsente la matrice nulle de 0
m,n
R
m,n
.
3.5 Solutions des exercices 71
(2) Ecrire une fonction mult(A,B) qui calcule de manire traditionnelle, par trois boucles im-
briques, le produit de deux matrices A et B aux dimensions que lon supposera compatibles.
(3) Ecrire une fonction transposed(B) qui retourne la matrice transpose de son argument B.
(4) crire une fonction dot(X,Y) qui retourne le produit scalaire de deux vecteurs (list) de
mme dimension.
(5) En remarquent que le terme c
i,j
du produit AB est le produit scalaire de la i-me ligne de
A avec la j-me colonne de B, et en utilisant la fonction dot(), et la matrice transpose de B
crire le produit A B en utilisant deux list comprehension imbriques.
Exercice 23. Algorithme de Horner.
Pour calculer la valeur dun polynme en un point x, lalgorithme de Horner est le plus co-
nomique. Le principe est dcrire le polynme p (x) = a
0
+ a
1
x + a
2
x
2
+ + a
n
x
n
sous la
forme
p (x) = a
0
+ x(a
1
+ x(a
2
+ x(a
3
+ + x(a
n1
+ x (a
n
)))))
crire lalgorithme puis la fonction correspondante horner(A,x), qui retourne la valeur de
p (x), o A est une liste contenant les coefficients a
i
Solutions des exercices
Solution 15 Le plus petit rel
1 >>> a,n=2.0,0
2 >>> while a>0.0 :
3 ... a,n = a/2, n+1
4 ...
5 >>> n
6 1076
Solution 16 Racines n-ime de lunit :
Solution la C :
1 from math import sin, cos
2 n = 200
3 S, P = 0.0,1.0
4 for k in range(n) :
5 S += complex(cos(2*k*pi/n), sin(2*k*pi/n))
6 P *= complex(cos(2*k*pi/n), sin(2*k*pi/n))
7 print(S, P)
Solution la Python
4
:
4
en Python 2, la fonction reduce() est une fonction intgre quil est donc inutile dimporter
72 Chapitre 3. Structures de contrle
1 from cmath import exp, pi
2 from operator import mul
3 from functools import reduce
4 n = 200
5 L = [exp(2j*k*pi/n) for k in range(n)]
6 S = sum(L)
7 P = reduce(mul, L)
8 print(S, P)
Solution 17 (1) Les 100 premiers termes
1 >>> x = 0.5
2 >>> -sum([x**k/k for k in range(1,101)])
3 -0.6931471805599451
4 >>> import math
5 >>> math.log(0.5)
6 -0.6931471805599453
Lalgorithme de Horner ( 3.5.9 page 76) permet de calculer cette somme de manire moins
gourmande en ressources et plus prcise :
1 >>> -horner([0]+[1/n for n in range(1,101)],0.5)
2 -0.6931471805599453
(2) La srie est numriquement stationnaire TODO
1 def myLog0(x) :
2 """
3 >>> x = 0.5
4 >>> myLog0(x)
5 (-0.693147180559945..., 48)
6 """
7 p = 0
8 xi = 1.0
9 A = (1.0/n for n in range(1,10000))
10 for (i,a) in enumerate(A) :
11 xi *= x
12 axi = a*xi
13 q = p + axi
14 if p == q :
15 return -q,i
16 p = q
17 return (-p,i)
3.5 Solutions des exercices 73
Solution 18 Le plus grand entier
1 >>> m = 2
2 >>> while type(m) == int :
3 ... m *= 2
4 ...
5 >>> m
6 2147483648L
Solution 19 2
n
= 0 et 2
n+1
= 0
1 >>> a, b, n = 1.0, 0.5, 1
2 >>> while a != 0 :
3 ... a, b, n = a*b, b/2, n+1
4 ... else :
5 ... print(n)
6 >>> n
7 47
Solution 20 Produit scalaire.
On dclare deux vecteurs test :
1 >>> X, Y = [0, 1, 1],[2, -1, 1]
Les programmeurs familiers du C criront sans doute :
1 >>> s = 0
2 >>> for i in range(len(X)) :
3 ... s += X[i]*Y[i]
4 >>> print (s)
5 0
On peut apparier X et Y en utilisant la fonction zip()
1 >>> s = 0
2 >>> for x,y in zip(X,Y) :
3 ... s += x*y
On peut aussi viter la boucle for et la variable s en utilisant la fonction intgre sum() et une
list comprehension :
74 Chapitre 3. Structures de contrle
1 >>> sum([x*y for x,y in zip(X,Y)])
On peut galement, (cest plutt plus conomique en mmoire) se dispenser de crer explicite-
ment la liste en utilisant une expression gnratrice (voir 4.3.4 page 85) :
1 >>> sum(x*y for x,y in zip(X,Y))
Cette instruction sadapte des vecteurs de taille quelconque.
On peut galement en faire une fonction que lon utilisera plus loin 21 page 70 :
1 def dot(X,Y) :
2 return sum(x*y for x,y in zip(X,Y))
Solution 21 Produit matrice vecteur.
On construit la matrice et le vecteur
1 >>> A=[[1,2,3],[0,1,0],[1,-1,0]]
2 >>> X=[1,1,1]
(1) Une boucle classique :
1 >>> n = len(X)
2 >>> Y = [0, 0, 0]
3 >>> for i in range(n) :
4 for j in range(n) :
5 Y[i] = Y[i] + A[i][j]*X[j]
6 >>> Y
7 [6, 1, 0]
(2) En utilisant les list comprehension. Pour un i fix, la boucle sur j qui calcule y[i] peut
scrire :
1 >>> Y[i] = sum([A[i][j]*X[j] for j in range(n)])
En observant que Y[i] est en fait le produit scalaire de la ligne A[i] avec le vecteur X, et
en utilisant lexercice 3.5.9 page prcdente, on obtient :
1 >>> Y[i] = sum([a*x for a,x in zip(A[i],X)])
Il faut ensuite boucler sur i pour affecter Y[i]. Or, le parcours des A[i] for i in
range(n) quivaut au parcours des L for L in A. On intgre cette construction dans une
list comprehension
3.5 Solutions des exercices 75
1 >>> Y = [sum([a*x for a,x in zip(L,X)]) for L in A]
Finalement, si lon utilise la fonction dot() de lexercice 20 page 70 dont la solution est en 3.5.9
page 73, on obtient linstruction la plus lisible, exprimant que llment Y
i
est le produit
scalaire de X et de la i-me ligne de A, cest dire
1 >>> Y = [dot(X,L) for L in A]
Solution 22 Produit matrice matrice :
(1) Fonction zeros(m,n) :
1 def zeros(m,n) :
2 return [[0 for j in range(n)] for i in range(m)]
Attention : on peut aussi penser crire return m*[n*[0]] qui retourne effectivement
une liste de listes avec les bonnes dimensions mais les m listes sont identiques, autrement dit
il ny a quune liste, et si on modifie une ligne de la matrice, toutes les lignes sont modifies.
Par exemple :
1 >>> C = 3*[2*[0]]
2 >>> C
3 [[0, 0], [0, 0], [0, 0]]
4 >>> C[0][0]=1
5 >>> C
6 [[1, 0], [1, 0], [1, 0]]
(2) Produit usuel :
1 def mult0(A,B) :
2 m,n,p = len(A),len(A[0]),len(B[0])
3 C = zeros(m,p)
4 for i in range(m) :
5 for j in range(p) :
6 C[i][j] = sum([A[i][k]*B[k][j] for k in range(n)])
On a remplac la boucle la plus imbrique (boucle sur k) par une somme sur une list compre-
hension.
(3) Transpose
1 def transposed(B) :
2 n,p = len(B),len(B[0])
3 return [[B[k][j] for k in range(n)] for j in range(p)]
ou bien :
76 Chapitre 3. Structures de contrle
1 return [[L[j] for L in B] for j in range(p)]
(4) Produit scalaire
1 def dot(X,Y) :
2 sum([x*y for x,y in zip(X, Y)])
(5) Produit.
Llment c
i,j
=
1kn
a
i,k
b
k,j
est le produit scalaire de la ligne i de A avec la colonne
j de B. Donc calculer la matrice C consiste faire
[[L.C pour les colonnes C de B] et pour les lignes L de A]
La i-me ligne de A est lA = A[i].
La j-me colonne de B, est la j-me ligne de la matrice transpose Bt.
Pour i et j fixs, c
i,j
vaut donc dot(A[i],Bt[j]).
1 def mult(A,B) :
2 Bt = transposed(B)
3 return [[dot(ligne,colonne) for colonne in Bt] for ligne in
A]
On peut ensuite tester avec les deux matrices :
1 >>> A = [[1,2,3],[0,1,0],[1,-1,0],[1,2,3]]
2 >>> B = [[0,1],[1,0],[1,1]]
Solution 23 Algorithme de Horner
p = a
n
pour i = n-1, n-2, ..., 0 faire
p = p*x + a
i
1 def horner(A,x) :
2 """
3 >>> A = [-3, -5, -1, 1]
4 >>> horner(A,3), horner(A,-1)
5 (0, 0)
6 >>> horner([0]+[1.0/n for n in range(1,101)],0.5)
7 0.693147180559945...
8 """
9 p = 0
10 for a in reversed(A) :
11 p = p*x + a
3.5 Solutions des exercices 77
Il est inutile dappeler les coefficients de A par leur numro A[i]. La variable a parcourt A dans
le bon ordre, lindice est inutilis.
CHAPITRE 4
Les types intgrs (builtins)
4.1. Les variables Python
Une variable Python est un tripl (nom, type, valeur).
En Python 3, les noms de variables doivent obir quelques rgles simples :
un nom de variable est une squence de lettres (a...z , A...Z) et de chiffres (0...9), qui doit toujours
commencer par une lettre.
Seules les lettres ordinaires sont autorises. Les lettres accentues, les cdilles, les espaces, les
caractres spciaux tels que $, #, @, etc... sont interdits, lexception du caractre _ (soulign ou
underscore).
La casse est significative (les caractres majuscules et minuscules sont distingus). Ainsi les noms
Chabal, chabal, CHABAL dsignent des variables distinctes.
En Python 3, les noms de variables peuvent contenir des lettres accentues.
Le tableau 4.1 donne la liste des 33 mots rservs ou mots-cl du langage Python 3
1
. Ces mots
cl ne peuvent bien entendu pas tre utiliss comme noms de variables.
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise
Tab. 1. Liste des mots cl de Python3
La valeur dune variable est dun type donn, ce type peut tre modifiable (se dit mutable en
anglais) ou non modifiable (on trouve aussi parfois le qualificatif immuable ou en anglais immu-
table).
Les types de base non modifiables sont int, float, tuple, str, bytes
Les types de base modifiables sont list, dict, bytearray
1
En Python 2 False, None, nonlocal et True, ne sont pas des mots-cl, tandis que exec et print sont des mots-cl.
80 Chapitre 4. Les types intgrs (builtins)
La valeur dune variable de type modifiable peut tre change en gardant la mme adresse m-
moire, donne par la fonction id(). Un exemple dutilisation de la fonction id() :
1 >>> id(1)
2 137163584
3 >>> i = 1
4 >>> id(i)
5 137163584
Linstruction id(1) cre la valeur 1 de type int, et renvoie ladresse de cette valeur, puis libre
les ressources cette adresse, puisquaucune rfrence ne pointe plus dessus.
Linstruction i = 1 cre nouveau la valeur 1 et lui associe le nomi. Ladresse de i est ladresse
de la valeur 1. Elle a t recr la mme adresse que la valeur 1 prcdente, cest peut-tre un
hasard.
Le seul moyen de changer la valeur dune variable dun type non modifiable est de recrer la nou-
velle valeur et de lassocier au nom de la variable par linstruction daffectation nom = valeur.
Ladresse mmoire de la nouvelle valeur est modifie.
1 >>> t = (0,1)
2 >>> id(t)
3 3071847852
id(t) est lidentificateur de la liste t est en quelque sorte son adresse mmoire, il est unique au
cours dune session Python et ne sera pas modifi.
1 >>> t[1] = 7
2 Traceback (most recent call last) :
3 ...
4 t[1] = 7
5 TypeError : 'tuple' object does not support item assignment
Les tuples sont non modifiables. Pour modifier un tuple, il faut en crer une copie modifie et
laffecter t. Son adresse nest plus la mme.
1 >>> t = (0,7)
2 >>> id(t)
3 3070871436
La mme suite dinstructions avec une liste ne produit pas derreur, et la liste ne change pas
dadresse :
4.2 Les types numriques (int, float, complex) 81
1 >>> t=[0,1]
2 >>> id(t)
3 3070746444
4 >>> t[1]=7
5 >>> id(t)
6 3070746444
Ces subtilits concernant les variables sont fondamentales pour comprendre le passage dargu-
ments par affectation dans le chapitre sur les fonctions (voir 5.1.2 page 119).
4.2. Les types numriques (int, float, complex)
Les types numriques en Python sont int, float, complex.
Les types numriques sont non modifiables.
Les entiers (int) sont cods sur un nombre variable et illimit doctets, et de ce fait sont illimits.
1 >>> i = 10**100
2 >>> i+1
3 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Les nombres complexes font partie du langage Python .
Pour dclarer un complexe, il existe plusieurs possibilits :
1 >>> z0 = complex(a,b)
2 >>> z1 = 1+3j
Si a et b sont deux rels ou entiers, la premire instruction affecte le complexe a+ib la variable
z0 et la seconde instruction affecte le complexe 1 + 3i z1.
En plus des oprations standard (addition, soustraction, multiplication, division, lvation la
puissance), Python dfinit les fonctions suivantes :
abs(x) : valeur absolue ou module complexe |x|
int(x) : partie entire (float et int seulement)
float(x) : conversion en float (float et int seulement)
divmod(x,y) : le couple (x//y, x%y) (float et int seulement)
complex(x,y) : le complexe x + iy . Par dfaut y vaut 0.
z.conjugate() : conjugu du complexe z (complex seulement)
pow(x,y) : lvation la puissance x
y
. x et y peuvent tre de nimporte quel type numrique.
82 Chapitre 4. Les types intgrs (builtins)
Diverses oprations et manipulations mathmatiques sur les types numriques sont possibles avec
les modules :
numbers classes numriques de base, oprations de bas niveau ;
math fonctions et constantes mathmatiques ;
cmath fonctions et constantes mathmatiques pour les complexes ;
decimal nombres dcimaux, virgule fixe ;
fractions nombres rationnels ;
random nombres pseudo-alatoires ;
4.3. Itrateurs et gnrateurs
4.3.1. Dfinition. En premire approche, il ny a pas grand inconvnient songer s-
quence (list ou tuple, ...) comme synonyme de itrable ou mme itrateur .
Le glossaire
2
de la documentation Python fournit les explications suivantes :
itrable : un objet capable de retourner ses items un par un. Les squences (list, str, tuple)
sont itrables, certains types comme dict, file sont itrables, ainsi que tous les types
que vous pouvez dfinir possdant une mthode __iter__() ou __getitem__(). Les
itrables peuvent tre utiliss dans les boucles for mais aussi partout o une squence
est ncessaire (fonctions zip(), map(), etc.). Lorsquun objet itrable est pass en argu-
ment la fonction intgre iter(), elle retourne un itrateur sur cet objet. Cet itrateur
permet de passer en revue les items de lobjet. En gnral il nest pas ncessaire dutili-
ser la fonction iter() ni de traiter directement avec litrateur. Linstruction for le fait
directement, en crant une variable itrateur temporaire non nomme pour la dure de
la boucle.
itrateur : un objet reprsentant un flux de donnes. Un appel rpt la mthode next() de
litrateur, retourne les items successifs items du flux. Lorsquil ny a plus ditem dispo-
nible, litrateur lve lexception StopIteration. Litrateur est alors puis. Tout ap-
pel ultrieur sa mthode next() lve lexception StopIteration nouveau. Les it-
rateurs doivent avoir une mthode __iter__() qui retourne lobjet itrateur lui-mme.
Ainsi tout itrateur est un itrable et peut, presque partout, tre utilis la place de li-
trable quil reprsente. Un exception toutefois : lorsque lon effectuer plusieurs cycles
complets ditrations sur un mme itrateur, la fin du premier cycle et les cycles sui-
vants, il apparatra comme un conteneur vide. Les objets itrables intgrs (list, dict,
str, etc.) recrent un nouvel itrateur pour chaque boucle for dans laquelle ils sont
utiliss.
gnrateur : une fonction qui retourne un itrateur. Cest une fonction ordinaire, sauf quelle
contient une instruction yield produisant une suite de valeurs destination dune boucle
for ou bien de la fonction next(). Chaque yield suspend temporairement lexcution
2
http://docs.python.org/py3k/glossary.html
4.3 Itrateurs et gnrateurs 83
du gnrateur, mmorise lendroit o il a t interrompu, et la valeur des variables lo-
cal au moment de linterruption. Ces valeurs sauvegardes sont ensuite rutilises la
prochaine invocation du gnrateur.
4.3.2. Itrateurs. Nous avons vu que la plupart des conteneurs peuvent tre parcourus en
utilisant une instruction for
1 for element in [1, 2, 3] :
2 print element
3 for element in (1, 2, 3) :
4 print element
5 for key in {'one' :1, 'two' :2} :
6 print key
7 for char in "123" :
8 print char
9 for line in open("myfile.txt") :
10 print line
Ce style daccs est clair, concis et pratique. Lutilisation ditrateurs imprgne Python et lunifie.
Derrire cette simplicit se cache la suite dopration suivante :
linstruction for appelle iter() sur lobjet conteneur.
Cette fonction renvoie un objet itrateur dfinissant une mthode next() qui accde les l-
ments dans le conteneur, un la fois.
Lorsquil ny a plus dlments, iter() lve une exception StopIteration qui dit la
boucle for de se terminer.
Exemple ditrateur :
1 >>> s = 'abc'
2 >>> it = iter(s)
3 >>> it
4 <iterator object at 0x00A1DB50>
5 >>> it.next()
6 'a'
7 >>> it.next()
8 'b'
9 >>> it.next()
10 'c'
11 >>> it.next()
12 Traceback (most recent call last) :
13 File "<pyshell#6>", line 1, in -toplevel
14 it. next()
15 StopIteration
84 Chapitre 4. Les types intgrs (builtins)
Pour ajouter un comportement ditrateur une classe, il suffit de dfinir une mthode __iter__
() qui renvoie un objet ayant une mthode next(). Si la classe dfinit next() , alors __iter__()
peut se limiter renvoyer self.
Voici un exemple ditrateur personnalis :
1 class Reverse :
2 """Iterator for looping over a sequence backwards"""
3 def __init__(self, data) :
4 self.data = data
5 self.index = len(data)
6 def __iter__(self) :
7 return self
8 def next(self) :
9 if self.index == 0 :
10 raise StopIteration
11 self.index = self.index - 1
12 return self.data[self.index]
13
14 >>> for char in Reverse('spam') :
15 ... print char
16 ...
17 m
18 a
19 p
20 s
4.3.3. Gnrateurs. Les gnrateurs sont un outil simple et puissant pour crer des it-
rateurs. Ce sont des fonctions ordinaires dont la particularit est dutiliser linstruction yield
chaque fois quils veulent renvoyer une donne. Lorsque que next() est appel, le gnrateur
reprend l o il stait interrompu (il mmorise les valeurs des donnes et quelle instruction a t
excute en dernier). Lexemple suivant montre quel point il est trivial de crer un gnrateur :
1 def reverse(data) :
2 for index in range(len(data)-1, -1, -1) :
3 yield data[index]
4 >>> for char in reverse('zeus a ete a suez') :
5 ... print char,
6 ...
7 zeus a ete a suez
4.4 Les squences tuples et list 85
Tout ce qui peut tre fait avec des gnrateurs peut aussi tre fait avec des itrateurs bass sur des
classes comme dcrit dans la section prcdente. Ce qui rend les gnrateurs si compacts est le
fait que les mthodes (__iter__()) et (next()) sont cres automatiquement.
Un autre point cl est que les variables locales et ltat de lexcution sont sauvs automatique-
ment entre les appels. Cela rend la fonction facile crire et beaucoup plus claire quune approche
utilisant les variables dinstance comme self.index et self.data. En plus de la cration de
mthodes et la sauvegarde de ltat automatiques, lorsque les gnrateurs terminent ils lvent
automatiquement lexception StopIteration. Ensemble, ces particularits facilitent la cration
ditrateurs sans plus deffort que lcriture dune fonction ordinaire.
4.3.4. Expressions gnratrices. Certains gnrateurs simples peuvent tre cods succinc-
tement comme des expressions qui utilisent une syntaxe similaire celle des list comprehensions
mais avec des parenthses au lieu de crochets. Ces expressions sont destines aux situations o le
gnrateur est immdiatement utilis par une fonction englobante. Les expressions gnratrices
sont plus compactes mais moins souples que les dfinitions de gnrateurs compltes. Elles ont
tendance tre plus conomes en mmoire que les list comprehensions quivalentes, mais beau-
coup plus voraces en temps dexcution. Exemples :
1 >>> sum(i*i for i in range(10)) # sum of squares
2 285
3 >>> xvec = [10, 20, 30]
4 >>> yvec = [7, 5, 3]
5 >>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
6 260
7 >>> from math import pi, sin
8 >>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))
9 >>> unique_words = set(word for line in page for word in line.
split())
10 >>> valedictorian = max((student.gpa, student.name) for student in
graduates)
11 >>> data = 'golf'
12 >>> list(data[i] for i in range(len(data)-1,-1,-1))
13 ['f', 'l', 'o', 'g']
Pour des raisons pdagogiques de simplicit, on parle des fonctions range(), sorted(), reversed
(), enumerate(), zip(), map(), filter() etc. qui sont en ralit des classes. Mais dans le
contexte prsent, elles sutilisent avec une syntaxe de fonction, qui nest autre que la syntaxe du
constructeur de la classe.
4.4. Les squences tuples et list
4.4.1. Les tuples. Un tuple est un ensemble de valeurs spares par des virgules, par exemple :
86 Chapitre 4. Les types intgrs (builtins)
1 >>> t = 12345, 54321, 'salut!'
2 >>> t
3 (12345, 54321, 'salut!')
4 >>> t[0]
5 12345
Les tuples peuvent tre imbriqus :
1 >>> t, (1, 2, 3, 4, 5)
2 ((12345, 54321, 'salut!'), (1, 2, 3, 4, 5))
Les tuples sont toujours entre parenthses. Les tuples, comme les chanes, sont non-modifiables :
il est impossible daffecter individuellement une valeur aux lments dun tuple.
1 >>> t = (1, 2, 3)
2 >>> t[0] = 5
3 Traceback (most recent call last) :
4 [...]
5 t[0]=5
6 TypeError : 'tuple' object does not support item assignment
Un problme particulier consiste crer des tuples 0 ou 1 lment : la syntaxe admet quelques
subtilits pour y parvenir. Les tuples vides sont construits grce des parenthses vides. Un tuple
un seul lment est construit en faisant suivre une valeur dune virgule (il ne suffit pas de mettre
une valeur seule entre parenthses). Par exemple :
1 >>> empty = ()
2 >>> singleton = 'salut', ##
3 >>> len(empty)
4 0
5 >>> len(singleton)
6 1
7 >>> singleton
8 ('salut',)
Linstruction t = (12345, 54321, 'salut') est un exemple demballage en tuple (tuple
packing) : les valeurs 12345, 54321 et 'salut' sont emballes ensemble dans un tuple. Lop-
ration inverse ( dballage de tuple -tuple unpacking-) est aussi possible :
1 >>> x, y, z = t
4.4 Les squences tuples et list 87
Le dballage dun tuple ncessite que la liste des variables gauche ait un nombre dlments gal
la longueur du tuple. Notez que des affectations multiples ne sont en ralit quune combinaison
demballage et dballage de tuples !
4.4.2. Le dcoupage (slicing). Les squences (chanes de caractres, listes, tuples) peuvent
tre adresss de diffrentes manires.
Il est important de rappeler que si L est une squence, linstruction y = L a pour effet de dsigner
y comme un alias de L. Cest dire que y et L ont mme adresse mmoire, le rsultat du test
y is L est True.
Pour crer une recopie de L dans y, il faut crire y = L[ :].
La manire la plus simple de rfrencer un lment de la squence L est de spcifier son index
entre crochets, le premier lment dune squence est en position 0 : L[0].
On peut galement prciser une tranche de squence : L[m :M] qui dsigne une copie de la
squence L[m],L[m+1]...,L[M-1]
1 >>> L = 'HelpA'
2 >>> L[4]
3 'A'
4 >>> L[0 :2]
5 'He'
6 >>> L[2 :4]
7 'lp'
Les index dans les tranches ont des valeurs par dfaut. La valeur par dfaut du premier index est
0, celle du second index est len(L). Ainsi, L[ :3] est une copie de la squence L[0], L[1],
L[2]. De mme L[3 :] est une copie de la squence L[3], L[4], ..., L[len(L)-1]
1 >>> L[ :2]
2 'He'
3 >>> L[2 :]
4 'lpA'
Voici un invariant utile des oprations de dcoupage : L[ :i] + L[i :] == L
1 >>> L[ :2] + L[2 :]
2 'HelpA'
3 >>> L[ :3] + L[3 :]
4 'HelpA'
Dans une opration de dcoupage L[m :M], un index qui est trop grand est remplac par la taille
de la squence, un index de fin infrieur lindice de dbut retourne une squence vide.
88 Chapitre 4. Les types intgrs (builtins)
1 >>> L[1 :100]
2 'elpA'
3 >>> L[10 :]
4 ''
5 >>> L[2 :1]
6 ''
Les index peuvent tre des nombres ngatifs pour compter partir de la droite. Lindice -1 dsigne
le dernier lment de la squence, -2 lavant dernier, etc. Le dcoupage galement est autoris
avec des index ngatifs.
Les index i et i-len(L) dsignent le mme lment de la squence L
1 >>> [L[i] is L[i-len(L)] for i in range(len(L))]
2 [True, True, True, True, True]
3 >>> L[-2]
4 'p'
5 >>> L[-2 :]
6 'pA'
7 >>> L[ :-2]
8 'Hel'
4.4.3. Les listes. Le type list possde dautres mthodes que celles dj rencontres. Voici
toutes les mthodes des objets de type list :
append(x) : quivalent a.insert(len(a), x)
extend(L) : rallonge la liste en ajoutant la fin tous les lments de la liste donne ; quivaut
a[len(a) :] = L.
insert(i,x) : insre un lment une position donne. Le premier argument est lindice
de llment avant lequel il faut insrer, donc a.insert(0, x) insre au dbut de la liste, et
a.insert(len(a), x) est quivalent a.append(x).
remove(x) : enlve le premier lment de la liste dont la valeur est x. Si cet lment nexiste
pas, lexception ValueError est mise.
pop([i]) : enlve llment prsent la position donne dans la liste, et le renvoie. Si au-
cun indice nest spcifi, a.pop() renvoie le dernier lment de la liste. Llment est aussi
supprim de la liste.
index(x) : retourne lindice dans la liste du premier lment dont la valeur est x. Il y a erreur
si cet lment nexiste pas.
count(x) : renvoie le nombre doccurrences de x dans la liste.
sort() : trie les lments lintrieur de la liste.
reverse() : inverse lordre des lments lintrieur de la liste.
Voici un exemple qui utilise toutes les mthodes des listes :
4.4 Les squences tuples et list 89
1 >>> a = [66.6, 333, 333, 1, 1234.5]
2 >>> print a.count(333), a.count(372.)
3 (2, 0)
4 >>> a.insert(2, -1)
5 >>> a.append(333)
6 >>> a.index(333)
7 1
8 >>> a.remove(333)
9 >>> a.pop(1)
10 -1
11 >>> a
12 [66.599999999999994, 333, 1, 1234.5, 333]
13 >>> a.reverse()
14 >>> a
15 [333, 1234.5, 1, 333, 66.599999999999994]
16 >>> a.sort()
17 >>> a
18 [1, 66.599999999999994, 333, 333, 1234.5]
Utiliser les listes comme des piles. Les mthodes des listes rendent trs facile lutilisation
dune liste comme une pile, o le dernier lment ajout est le premier lment rcupr (pile
LIFO, pour last-in, first-out). Pour ajouter un lment au sommet de la pile, utilisez la mthode
append(). Pour rcuprer un lment du sommet de la pile, utilisez pop() sans indice explicite.
1 >>> pile = [3, 4, 5]
2 >>> pile.append(6)
3 >>> pile.append(7)
4 >>> pile.pop()
5 7
6 >>> pile.pop()
7 6
8 >>> pile.pop()
9 5
10 >>> pile
11 [3, 4]
Utiliser les listes comme des files dattente. Vous pouvez aussi utiliser facilement une liste
comme une file dattente, o le premier lment ajout est le premier lment retir (FIFO, pour
first-in, first-out). Pour ajouter un lment la fin de la file, utiliser append(). Pour rcuprer un
lment du dbut de la file, utilisez pop(0) avec 0 pour indice.
Par exemple :
90 Chapitre 4. Les types intgrs (builtins)
1 >>> file = ["Gaetan", "Gudule", "Gerard"]
2 >>> file.append("Gaston") # Gaston arrive
3 >>> file.append("Gontran") # Gontran arrive
4 >>> file.pop(0)
5 'Gaetan'
6 >>> file.pop(0)
7 'Gudule'
8 >>> file
9 ['Gerard', 'Gaston', 'Gontran']
Linstruction del. Linstruction del permet la suppression dun lment de liste lorsque lon
dispose de son indice au lieu de sa valeur. del peut aussi tre utilis pour enlever des tranches
dans une liste (ce que lon a fait prcdemment par remplacement de la tranche par une liste vide).
Par exemple :
1 >>> a=[-1, 1, 66.6, 333, 333, 1234.5]
2 >>> del a[0]
3 >>> del a[2 :4]
del peut aussi tre utilis pour supprimer des variables compltes :
>>> dela
4.5. Les chanes de caractres (str, bytes, bytearray)
Les chanes de caractres font partie des squences Python .
Unicode, utf-8, ASCII, Windows-1252, ISO 8859-1, Latin-1, etc... tous ces sigles, symboles, abr-
viations sont un vrai ddale pour le programmeur. Un peu de tri est ncessaire pour sy retrouver.
4.5.1. Identification et codage des caractres.
Identification Unicode. Le Consortium Unicode a dvelopp Unicode
3
qui est une norme vi-
sant ordonner et attribuer (presque) tout caractre de (presque) tous les langages un nom et
un identifiant numrique unique, appel point de code. Lidentifiant numrique est de la forme
U+xxxxx ou xxxxx est un nombre hexadcimal. Ces points de codes sont regroups en 17 plans
Unicode de 16
4
= 65536 points de code chacun. Seuls les plans 0 et 1 sont actuellement utiliss
pour un usage courant. On y trouve ple-mle : caractres usuels, idogrammes, symboles ma-
thmatiques, flches, symboles et formes gomtriques diverses, smileys, pices de Mah-Jong,
dominos, cartes jouer etc.. Prvu pour coder jusqu 1114112 points de code, on recense actuel-
lement 245000 points de code utiliss.
3
http://fr.wikipedia.org/wiki/Unicode
4.5 Les chanes de caractres (str, bytes, bytearray) 91
Le code Unicode de chaque caractre est un simple identifiant. Il est totalement indpendant de
son codage logiciel (sous forme doctets) qui reste discrtion des plateformes, et des logiciels.
Unicode ne se mle pas de codage informatique, contrairement ce que suggre son nom. Unicode
nest que descriptif et taxinomique.
Le codage informatique des caractres est lobjet du paragraphe suivant.
Le codage logiciel. Les diffrentes normes ASCII, ISO 8859-1, Windows-1252, utf-8, etc...
grent problme du codage de ces caractres en machine.
(1) ASCII : historiquement ASCII
4
est apparu le premier dans les annes 60, il propose le codage
sur un unique octet, de 2
7
= 128 caractres de base
5
. Sur les 8 bits que compte un octet, un bit
est requis pour dautres considrations techniques. Les caractres accentus et les caractres
particuliers chaque langue sont absents de ce mode de codage.
(2) ISO 8859 et ses variantes : le huitime bit a t ensuite utilis pour reprsenter les caractres
accentus. Seuls sont disponibles 2
8
= 256 caractres, ce qui est insuffisant pour couvrir les
caractres utiles de tous les langages candidats. Pour rgler ce problme, sont apparus les
pages de code encore largement utilises de nos jour. Chacune de ces pages de code dtourne
lutilisation de ce fameux huitime bit pour le spcialiser dans la reprsentation dun jeu de
caractres particulier.
6
La norme ISO-8859 ou Latin-1 dcline plusieurs de ces pages de code. Pour ce qui concerne
lEurope Occidentale, la page de code ISO8859-1 est la rfrence. Les pages de code Windows-
1252, MacRoman, Adobe Latin x en sont des variantes cres par Microsoft, Apple, Adobe
etc...
ISO-8859-2 ou Latin-2 prend en charge certaines langues dEurope centrale, ISO-8859-3 ou
Latin-3 prend en charge les langues dEurope du sud et lespranto, ISO 8859-11 prend en
charge le tha etc..
La page de code ISO 8859-15 est une volution de ISO 8859-1 incluant les sigles montaires
et les ligatures comme .
Toutes ces pages de code incluent et sont compatibles avec le codage ASCII.
(3) utf-8
7
: le codage utf-8 est une spcification de codage pour les points de code Unicode de
U+0000 U+D7FF et de U+E000 U+10FFFF et seulement ceux-l. Les caractres sont cods sur
un nombre doctets variable. Pour chaque caractre, les premiers bits indiquent sur combien
doctets est cod le caractre. Plus prcisment :
8
4
ASCII :American Standard Code for Information Interchange
5
Les caractres ASCII affichables sont les suivants : !"#$%&'()*+,-./ 0123456789 :;<=>? @ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_ `abcdefghijklmno pqrstuvwxyz{|}~
6
Le huitime bit de la page de code ISO-8859-1 permet la reprsentation, en sus des caractres ASCII, des caractres
suivants :
-
7
utf-8 pour UCS Transformation Format 8 bits ou UCS signifie Universal Character Set
8
http://fr.wikipedia.org/wiki/UTF-8
92 Chapitre 4. Les types intgrs (builtins)
Les caractres ayant une valeur scalaire de 0 127 (point de code attribu
de U+0000 U+007F) sont cods sur un seul octet dont le bit de poids fort est
nul.
Les points de code de valeur scalaire suprieure 127 sont cods sur plu-
sieurs octets. Les bits de poids fort du premier octet forment une suite de 1 de
longueur gale au nombre doctets utiliss pour coder le caractre, les octets
suivants ayant 10 comme bits de poids fort. Cette rgle est image dans le
tableau suivant :
Reprsentation binaire UTF-8 Signification
0xxxxxxx 1 octet codant 1 7 bits
110xxxxx 10xxxxxx 2 octets codant 8 11 bits
1110xxxx 10xxxxxx 10xxxxxx 3 octets codant 12 16 bits
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4 octets codant 17 21 bits
Tab. 2. Codage Utf-8, nombre doctets
Tant que lon en reste aux caractres ASCII, les choses sont assez simples. Pour les caractres
accentus ou les alphabets exotiques, la version 2 de Python est limite.
Cest dailleurs une des raisons qui ont amen au dveloppement de la version 3 de Python. Le
traitement des chanes de caractres a radicalement chang entre les sries 2.x et 3.x de Python.
Les chanes de caractres Python sont des squences non modifiables (immutables).
Le type chane de caractres est le type str. Toutes les chanes de caractres Python sont des
squences de caractres Unicode.
4.5.2. Comparatif sommaire Python 2 et 3.
Python 3. Pour crer une chane de caractres, il suffit de linclure entre apostrophes (quote
') ou guillemets (double quote "). On peut aussi les inclure entre triple apostrophes ou triple
guillemet. La chane a suivante est obtenue sur un clavier franais, en maintenant la touche Alt-
Gr enfonce et en tapant certaines lettres du clavier.
1 >>> a = ""
2 >>> b = 'Python'
Pour viter la plonge dans les arcanes de la reprsentation des chanes de caractres exotiques,
il est sage de se limiter aux caractres accentus, et dutiliser le codage utf-8 pour vos fichiers
sources Python.
Le type bytes
9
ressemble au type str avec quelques diffrences :
une variable bytes ne peut contenir que des caractres ASCII ;
9
Le type bytes nexiste pas en Python2
4.5 Les chanes de caractres (str, bytes, bytearray) 93
une variable bytes se dclare comme une chane de caractres ASCII, prcde du caractre
'b'.
laccs un lment dune variable bytes retourne le code ASCII du caractre, un entier dans
lintervalle [0, 255] ;
1 >>> a = b'avd'
2 >>> a[1]
3 118
Pour transformer un bytes en str, il faut utiliser la mthode decode() :
1 >>> b = b'azerty'
2 >>> print (b)
3 b'azerty'
4 >>> b.decode()
5 'azerty'
Le type bytesarray est analogue au type bytes mais modifiable. Il possde la plupart des m-
thodes propres aux squences modifiables (listes, dictionnaires, ...).
Python 2. En Python2 lorsque lon doit manipuler des chanes de caractres contenant des
caractres non-ASCII, il est conseill dutiliser le type unicode, obtenu en faisant prcder la
chane par la lettre u.
1 >>> x = u''
2 >>> x
3 >>> print x, type(x)
4 >>> v = '$eb'
5 >>> v
6 >>> print v, type(v)
7 >>> u + v #ouuups !
8 >>> v = u'eb'
9 >>> u + v #yes !
Il est impossible de concatner une chane str avec une chane unicode. On a donc tout intrt
utiliser systmatiquement le type unicode, donc faire prcder toutes les chanes constantes
par le caractre u.
En rsum. Si lon vient de Python2 et que lon veut passer Python3, on peut retenir les
principes suivants, qui bien que pas tout fait exacts, viteront de nombreuses erreurs :
le type unicode de Python2 devient le type str de Python3 (standard) ;
le type str de Python2 devient le type byte de Python3.
94 Chapitre 4. Les types intgrs (builtins)
4.5.3. Encodage et dcodage. Illustrons ce qui concerne lencodage par un exemple. En
Python la mthode str.encode(format) permet dencoder une chane suivant une page de
code donn.
1 >>> lc = ['a','','']
2 >>> for c in lc :
3 ... ec = c.encode('utf8')
4 ... ec, len(ec), ec[0]
5 (b'a', 1, 97)
6 (b'\xc3\xa9', 2, 195)
7 (b'\xe2\x82\xac', 3, 226)
On constate quen utf-8, le 'a' est cod sur un octet, le '' sur 2 octets et le '' sur 3 octets
1 >>> codes=['utf8','Windows-1252','ISO 8859-15','MacRoman']
2 >>> for code in codes :
3 c = ''.encode(code)
4 print ('{ :13s} : { :15s}, { :d} octets'.format(code, c, len
(c)))
5
6 utf8 : b'\xe2\x82\xac', 3 octets
7 Windows-1252 : b'\x80' , 1 octets
8 ISO 8859-15 : b'\xa4' , 1 octets
9 MacRoman : b'\xdb' , 1 octets
Les diffrents codages utf-8, Windows-1252, ISO 8859-15 et MacRoman nont pas la mme re-
prsentation du caractre ''.
4.5.4. Manipulations usuelles. Laide en ligne sur la classe str est trs complte.
Puisque les chanes de caractres sont immuables, chacune des mthodes de str que lon sattend
voir modifier linstance appelante, renvoie en ralit une copie modifie, lappelant ne peut pas
tre modifi in-situ.
Les mthodes les plus courantes sont :
capitalize() retourne une copie de la chane avec la premire lettre en majuscule.
count(sub, start=0, end=-1) retourne le nombre doccurrences (sans recouvrement) de
la chane sub dans lintervalle start :end
find(sub, start=0, end=-1) retourne lindice du premier caractre de la chane sub si
elle figure dans lintervalle start :end. Retourne -1 si elle na pas t trouve.
format()voir 4.5.6 page 96
index(sub, start=0, end=-1)comme find() mais lve lexception ValueError si sub
nest pas trouve.
4.5 Les chanes de caractres (str, bytes, bytearray) 95
join(iterable) concatne les lments de iterable, le sparateur entre les lments tant
linstance appelante. Si un des lments de iterable nest pas une chane, lexception TypeError
est leve. Exemple :
1 >>> ' * '.join(['a','b','c'])
2 'a * b * c'
lower() retourne la chane en lettres minuscules.
upper() retourne la chane en lettres majuscules.
strip([chars]) supprime en dbut et en fin de chane toutes les occurrences de tous les
caractres de chars. Si chars est omis, les espaces sont supprims.
1 >>> ' ,;;;; Ossau! ///'.strip(' ,;!/')
2 'Ossau'
replace(old, new[, count]) retourne une copie de la chane dans laquelle au plus count
occurrences de old ont t remplaces par new. Si count est omis toutes les occurrences sont
remplaces.
split([sep[, maxsplit]]) retourne la liste des mots de la chane, utilisant sep comme
sparateur. Si maxsplit est donn, la liste aura une longueur dau plus maxsplit+1. Si sep
est omis, tout espace sera sparateur. (Voir la doc pour quelques subtilits)
strip(chars='\t\n\r\x0b\x0c') retourne une chane de caractres dans laquelle ont t
supprims tous les caractres spcifis par largument chars, en dbut et fin de chane. Par
dfaut, chars contient tous les espaces (voir string.whitespace. Par exemple :
1 >>> '% : ;\Lionel Terray;//'.strip(';/ :% ')
2 'Lionel Terray'
4.5.5. Le module string. Ce module propose quelques constantes permettant de connatre la
nature dun caractre ainsi que quelques fonctions, quivalentes aux mthodes de la classe str.
Les instructions suivantes listent le contenu de certaines de ces constantes. Le rsultat devrait tre
clair :
1 >>> import string
2 >>> keys = dir(string)
3 >>> for key in keys :
4 ... key, getattr(string, key)
5 [...]
6 ('ascii_letters', '
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
7 ('ascii_lowercase', 'abcdefghijklmnopqrstuvwxyz')
8 ('ascii_uppercase', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
9 ('capwords', <function capwords at 0xb71b17ec>)
10 ('digits', '0123456789')
96 Chapitre 4. Les types intgrs (builtins)
11 ('hexdigits', '0123456789abcdefABCDEF')
12 ('octdigits', '01234567')
13 ('punctuation', '!"#$%&\'()*+,-./ :;<=>?@[\\]^_`{|}~')
14 ('whitespace', ' \t\n\r\x0b\x0c')
La fonction string.capwords() prend une chane en argument et retourne cette chane capita-
lise (la premire lettre de chaque mot a t mise en majuscule).
1 >>> string.capwords('mont blanc')
2 'Mont Blanc'
4.5.6. Formatage. Jusquici nous avons utilis deux manires pour afficher des valeurs : en
utilisant la fonction print()
10
ou bien en donnant simplement le nom de la variable imprimer.
1 >>> a = 12
2 >>> print(a)
3 12
4 >>> a
Pour formater plus finement les sorties, on dispose trois mthodes :
(1) utiliser les mthodes adaptes de la classe str (recommand) ;
(2) utiliser loprateur de formatage % :
format%variables
comme pour la fonction sprintf() du langage C;
(3) Manipulez soi-mme les chanes de caractres. Pour convertir nimporte quelle valeur en
chane de caractres il suffit de la passer la fonction repr(), ou str().
La mthode format() de la classe str. La mthode format() de la classe str fonctionne par
champs de remplacement (replacement fields) placs entre accolades {}.
On peut accder aux arguments par position. La chane formater contient des champs {0}, {1
}, {2} etc., qui seront remplacs par les valeurs (formates) des arguments passs la mthode
str.format() dans lordre indiqu :
1 >>> sommet, massif = 'Golden Peak', 'Karakoram'
2 >>> "Le {0} est dans le massif du {1}".format(sommet, massif)
3 'Le Golden Peak est dans le massif du Karakoram'
4 >>> "Le {} est dans le massif du {}".format(sommet, massif)
5 'Le Golden Peak est dans le massif du Karakoram'
6 >>> "Dans le {1} se trouve le {0}".format(sommet, massif)
7 'Dans le Karakoram se trouve le Golden Peak'
10
En Python 2 il sagit dune instruction print
4.5 Les chanes de caractres (str, bytes, bytearray) 97
On peut accder aux attributs des arguments par leur nom :
1 >>> c = 3-5j
2 >>> 'Re{0} = {0.real}'.format(c)
3 'Re(3-5j) = 3.0'
Le formatage des arguments peut tre plus prcis, en utilisant le principe des formats C . Par
exemple :
1 >>> import math
2 >>> "pi :{0 :+12.3f}; {0 :12.5E}".format(math.pi)
3 'pi : +3.142; 3.14159E+00'
Il est possible daligner les sorties droite ou gauche, avec ou sans caractre de remplissage
laide des spcificateurs <,^,> :
1 >>> import math
2 >>> "pi :{0 :<12.3f};{0 :*>12.5g}".format(math.pi)
3 'pi :3.142 ;******3.1416'
Extrait et traduit de la documentation Python , voici quelques spcifications de format utilises.
La forme gnrale dun spcificateur de format est la suivante (tous les spcificateurs sont facul-
tatifs) :
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
fill : est le caractre de remplissage, autre que }
align : est le caractre dalignement
< : align gauche,
> : align droite,
^ : centr)
sign : pour les types numriques, un des caractres +,-,
+ : permet dobtenir un affichage sign
- : laffichage est sign seulement sil est ngatif, cest le comportement par dfaut,
: (espace) laffichage est sign sil est ngatif, et prcd dun espace sil est positif
, : remplace le point dcimal par une virgule
width : est un entier indiquant la largeur minimale du champ
precision : est un entier donnant le nombre de dcimales pour les rels flottants
type : est un des caractres de lensemble {b,c,d,e,E,f,F,g,G,n,o,s,x,X,%}
type chanes de caractres :
s ou rien : format chane de caractres, cest le type par dfaut ;
types entiers :
b : format binaire (base 2) ;
98 Chapitre 4. Les types intgrs (builtins)
c : convertit lentier en sa reprsentation Unicode ;
d : format dcimal (base 10) ;
o : format octal (base 8) ;
x, X : format hexadcimal (base 16), utilisant des lettres minuscules ou majuscule ;
types float. Les entiers peuvent utiliser ces spcificateurs de formats
e, E : notation exponentielle ou scientifique (1.0e+2 par exemple) utilisant e ou E
pour prcder lexposant
f, F : affiche le rel en virgule fixe, nan et inf pour not a number et linfini
g, G : format gnral. Pour une prcision donne, p >= 1, arrondit le nombre p
chiffres significatifs et formate le rsultat en virgule fixe ou bien notation
scientifique suivant sa valeur.
n : nombre. Analogue g, mais en tenant compte des particularits locales (point
ou virgule dcimale, sparation des milliers)
% : pourcentage. Multiplie le nombre par 100 and et laffiche en virgule fixe, suivi
du caractre %
None : analogue g
Les fonctions str() et repr(). La fonction str() renvoie des reprsentations faciles lire par
les humains, alors que repr() renvoie des reprsentations lisibles par linterprteur Python. De
nombreuses valeurs, comme les nombres ou les structures (listes, dictionnaires), ont la mme
reprsentation par les deux fonctions. En revanche, les chanes de caractres et les nombres
virgule flottante, ont deux reprsentations distinctes.
Quelques exemples :
1 >>> s = 'Salut, tout le monde.'
2 >>> str(s),repr(s)
3 ('Salut, tout le monde.', "'Salut, tout le monde.'")
4 >>> s
5 'Salut, tout le monde.'
6 >>> str(0.1)
7 '0.1'
1 >>> x,y = 3.25, 150
2 >>> print ('x={ :f} tandis que y={ :f}'.format(x,y))
3 x=3.250000 tandis que y=150.000000
4 >>> print ('x=' + str(x) + ' tandis que y=' + str(y))
5 x=3.25 tandis que y=150
Utilisation de loprateur %. Pour formater les sorties, les habitus du C et du C++ prf-
reront sans doute utiliser loprateur % plutt que la mthode format() de la classe str. On en
dcrit ici quelques lments.
4.6 Les ensembles (set et frozenset) 99
La forme usuelle est donne par ce premier exemple qui cre une chane contenant math.pi sur
5 positions, avec 3 chiffres aprs la virgule :
1 >>> import math
2 >>> 'pi vaut : %5.3f' % math.pi
3 'pi vaut : 3.142'
Le %5.3f est un descripteur de format. Sil y a plus dun descripteur de format dans la chane de
caractres, vous devez passer un tuple comme oprande de droite, comme dans cet exemple :
1 >>> sommet = 'Mont Blanc'
2 >>> altitude = 4807
3 >>> 'Le %s culmine %d m' % (sommet, altitude)
4 'Le Mont Blanc culmine 4807 m'
La plupart des formats fonctionnent exactement comme en C et exigent que vous passiez le type
appropri
11
.
Ce mode de formatage nest pas document dans la version 3.2 de Python , mais seulement dans
les versions 2.x.
4.5.7. Autres fonctionnaliss pour le . Dans http://docs.python.org/release/3.1.
3/library/stdtypes.html, on trouvera les mthodes de la classe str
chr(i) retourne le caractre dont le code Unicode est lentier i. Par exemple, chr(97) re-
tourne 'a'. Largument i doit tre compris dans lintervalle [0, 1114111].
ord(c) linverse de la fonction chr(). Retourne le code Unicode (Unicode code point dans
la terminologie Unicode) de largument, qui doit tre un caractre Unicode.
str(c,code) pour transformer une chane de caractres c, code au format code, en une
chane de caractres Python code suivant le codage par dfaut, il faut utiliser ce constructeur
de la classe str.
4.6. Les ensembles (set et frozenset)
Python comporte un type de donnes pour reprsenter des ensembles. Un set est une collection
(non ordonne) sans lments dupliqus. Les emplois basiques sont le test dappartenance et l-
limination des entres dupliques. Les objets ensembles supportent les oprations mathmatiques
comme
lunion avec loprateur '|'
lintersection avec loprateur '&'
la diffrence avec loprateur '-' et
la diffrence symtrique (dfinie par AB = A B A B) avec loprateur '^' .
11
On trouvera une description plus complte de ces formats ladresse http://docs.python.org/library/
stdtypes.html
100 Chapitre 4. Les types intgrs (builtins)
Les instructions suivantes en donnent une dmonstration succincte :
1 >>> a = set('abracadabra')
2 >>> b = set('alacazam')
3 >>> a
4 set(['a', 'r', 'b', 'c', 'd'])
5 >>> a-b
6 set(['r', 'b', 'd'])
7 >>> a|b
8 set(['a', 'c', 'b', 'd', 'm', 'l', 'r', 'z'])
9 >>> a&b
10 set(['a', 'c'])
11 >>> a^b
12 set(['b', 'd', 'm', 'l', 'r', 'z'])
13 >>> 'z' in a
14 True
Python propose galement le type frozenset qui est analogue au type set mais non modifiable.
4.7. Les dictionnaires (dict)
Le type dictionnaire (dict) est intgr Python .
Cette section prcise et complte ce qui a t vu la section 2.9 page 41.
Comme dans un dictionnaire ordinaire o les lments sont des couples (mot : explication), les
lments des dictionnaires Python sont des couples (cl :valeur). Les cls sont les index, qui
peuvent tre de nimporte quel type non-modifiable et chaque cl est unique dans un mme dic-
tionnaire.
Les chanes et les nombres peuvent toujours tre des cls.
Un couple daccolades cre un dictionnaire vide : {}.
Les instructions suivantes crent toutes le mme dictionnaire {'un' :1,'deux' :2} :
1 >>> {'un' :1,'deux' :2}
2 >>> dict({'un' :1,'deux' :2})
3 >>> dict(un=1,deux=2)
4 >>> dict(zip(('un','deux'),(1,2)))
5 >>> dict([['un',1],['deux',2]])
Si d est un dictionnaire, les oprations supportes par d sont les suivantes :
len(d) retourne le nombre ditems de d ;
d[key] retourne la valeur associe la cl key. Si key nest pas une cl de d, lexception
KeyError est leve ;
4.8 Les exceptions (exceptions) 101
d[key] = valeur affecte valeur la cl key, avec cration ou remplacement de la valeur
suivant que la cl existe dj ou pas. Lancienne valeur est alors perdue ;
deld[key] supprime litem d[key] sil existe, lve lexception KeyError sinon ;
d.pop(key[, default]) si la cl key existe dans d, elle est supprime et sa valeur retourne.
Sinon, default est retourn. Si default nest pas donn, et la cl key nest pas dans d, alors
lexception KeyError est leve.
key in d retourne True si d contient la cl key, False sinon ;
d.clear() supprime tous les items de d ;
d.copy() retourne une copie de d.
d.keys() retourne une vue des cl du dictionnaire. En Python 2, retourne une liste des cls
de d. La diffrence entre une vue des cls et une liste des cls est que la vue est dynamique,
elle est mise jour au fur et mesure de lvolution de d, tandis que la liste des cls est un
instantan de ltat des cls au moment de sa cration.
d.items() retourne une vue des items du dictionnaires (cest dire des couples (cl, valeur))
d.values() retourne une vue des valeurs du dictionnaire (trie dans le mme ordre que la
vue des cls)
Exemple dutilisation des vues :
1 >>> d = {'un' :1,'deux' :2}
2 >>> keys = d.keys()
3 >>> keys
4 dict_keys(['un', 'deux'])
5 >>> d['infini'] = 'beaucoup'
6 >>> keys
7 dict_keys(['un', 'deux', 'infini'])
4.8. Les exceptions (exceptions)
Lorsquun erreur dexcution survient, Python lve une exception. Le programme stoppe et Py-
thon affiche la pile dappels, et lexception.
Il est possible dcrire des programmes qui prennent en charge des exceptions spcifiques. Lexemple
suivant, interroge lutilisateur jusqu ce quun entier valide ait t saisi, et lui permet dinter-
rompre le programme en utilisant Ctrl-C ou une autre combinaison de touches reconnue par le
systme dexploitation (il faut savoir quune interruption produite par lutilisateur est signale en
levant lexception KeyboardInterrupt).
1 while 1 :
2 try :
3 x = int(input(u"Veuillez entrer un nombre : "))
4 break
5 except ValueError :
102 Chapitre 4. Les types intgrs (builtins)
6 print u"Ae! Ce n'tait pas un nombre valide. Essayez encore
..."
Fonctionnement :
La clause try : les instructions entre les mots-cls try et except est excute.
Sil ne se produit pas dexception, la clause except est ignore, et lexcution du try est
termine.
Si une exception se produit, le reste de la clause try est ignor. Puis si son type correspond
lexception donne aprs le mot-cl except, la clause except est excute, puis lexcution
reprend aprs linstruction try.
Si une exception se produit qui ne correspond pas lexception donne dans la clause except,
elle est renvoye aux instructions try extrieures.
Linstruction raise vous permet de lever vous mme une exception.
Par exemple :
1 def get_age() :
2 age = input('Please enter your age : ')
3 if age < 0 :
4 raise ValueError, '%s is not a valid age' % age
5 return age
Linstruction raise prend deux arguments : le type de lexception et une chane de caractre qui
dcrit lexception.
ValueError est une exception standard.
La liste complte des exceptions :
>>> help('exceptions')
Les exceptions les plus courantes :
Accder une cl non-existante dun dictionnaire dclenche une exception KeyError
Chercher une valeur non-existante dans une liste dclenche une exceptionValueError.
Appeler une mthode non-existante dclenche une exception AttributeError.
Rfrencer une variable non-existante dclenche une exception NameError.
Mlanger les types de donnes sans conversion dclenche une exception TypeError.
4.8 Exercices 103
Exercices
Exercice 24. crire une expression qui vaut True si lentier n est pair et False dans le cas
contraire.
Exercice 25. Consultez la liste des rpertoires dans lesquels linterprteur recherche les modules.
Combien y a-t-il de rpertoires distincts ?
Exercice 26. Builtins
Depuis une session Python
(1) dterminer le type de lobjet __builtins__
(2) Affecter la variable L une liste des cls de __builtins__
(3) que vaut L[42] ?
(4) Trouver laide sur la fonction sum
Exercice 27. Formatage.
crire une table des carrs et des cubes prsente comme suit :
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
Exercice 28. Transformer la chane de caractre "3.14" en un flottant.
Exercice 29. Chanes
Soit la chane de caractres
a='1.0 3.14 7 8.4 0.0'
Ecrire une instruction unique utilisant les fonctions et mthode float() et split(), qui construit
la liste de rels
[1.0, 3.14, 7.0, 8.4, 0.0]
partir de a.
Exercice 30. Chanes
Soit la chane de caractres C="(1.0, 2.0)(3, 4)\n". Trouver une suite dinstructions per-
mettant den extraire les deux nombres complexes x=1+2j et y=3+4j. On pourra par exemple :
104 Chapitre 4. Les types intgrs (builtins)
(1) Nettoyer C de son '\n' C='(1.0, 2.0)(3, 4)
(2) Remplacer ', ' par ','C='(1.0,2.0)(3,4)'
(3) Scinder (=split()) la chane en deux C=['(1.0,2.0)', '(3,4)']
(4) A laide de la fonction eval() et dun dballage darguments, instancier le complexe 1+2j
partir de'(1.0,2.0)'
Exercice 31. Chanes, module string
(1) Rcuprer le fichier HUMOUR.txtde chap2-premiersPas, lire son contenu et supprimez tous
les signes de ponctuation, ainsi que les -.
(2) Enregistrer le rsultat dans un fichier HUMOUR-propre.txt
Exercice 32. Que fait la suite dinstructions :
1 >>> F = open('toto.csv')
2 >>> [[[g.strip() for g in f.strip().split(';')] \
3 for f in e.strip().split('\n')] \
4 for e in F.readlines()[1 :]]
5 >>> F.close()
Peut-on amliorer ?
Exercice 33. Formatage
On donne une liste de darticles et la liste des prix correspondants. crire une instruction qui
imprime la liste des (prix : article). Par exemple
1 >>> articles = ['mousqueton', 'reverso', 'crochet',
2 'baudrier', 'chausson', 'magnesie']
3 >>> prix = [5,25,5,80,120,2]
produira laffichage
1 mousqueton : 5
2 reverso : 25
3 crochet : 5
4 baudrier : 80
5 chausson : 120
6 magnesie : 2
Exercice 34. Chanes, encodage
(1) crire la chane de caractres il vous en cotera 45 dans deux fichiers texte : lun code
en utf-8, lautre en ISO 8859-15.
4.8 Exercices 105
(2) crire un script utf2win.py qui lit un fichier texte encod en utf-8, et qui le sauvegarde
avec lencodage Windows-1252. On suppose connu lencodage du fichier lu (en principe
cest lencodage par dfaut de votre systme). Pour dterminer lencodage dun fichier texte,
il nexiste pas de mthode absolument sre. La commande Unix file permet dans certains
cas, (mais pas toujours) de le dterminer :
$ echo ''> toto
$ file toto
toto : UTF-8 Unicode text
Exercice 35. Lecture-criture de fichiers
lire le contenu du fichier humour.txt, crire son contenu lcran en majuscule.
demander lutilisateur un nom de fichier, le lire et recopier son contenu, avec fer droite,
dans le fichier HUMOUR.txt.
Crer une liste de votre choix, picklez la dans un fichier liste.pic, unpicklez-la dans une
variable zoe
Exercice 36. Lecture
(1) Lors de la lecture dun fichier, le programme lit la chane de caractres s='1;2; 3; 4; 5'.
(2) Quelle instruction unique permet den faire la liste dentiers l=[1,2,3,4,5] ?
(3) Idem, avec s='1;2; 3; 4; 5;;'
(4) Idem, avec s='1;2; 3; -4; 5;;' et on ne garde dans l que les entiers positifs.
Exercice 37. Lecture sur fichier
(1) Ecrire un script qui cre un dictionnaire, d, dont les cls et les lments sont lus sur le fichier
Octave
12
suivant :
# Created by Octave 2.9.12
# name : z
# type : complex scalar
(1,2)
(2) Amliorer le script prcdent pour quil prenne en compte les enregistrements dans le mme
fichier Octave, du type suivant :
# name : chaine
# type : string
hello
(3) Mme question pour des variables matrices :
# name : M
# type : matrix
# dimensions : 2 4
1 2 7 6
2 3 8 7
12
Octave est un logiciel libre de calcul scientifique trs robuste, analogue Scilab, Matlab
106 Chapitre 4. Les types intgrs (builtins)
Les cls sont les noms des variables et les lments sont les valeurs de ces variables. On testera
les instructions programmes sur le fichier vars.oct.
Exercice 38. Lecture sur fichier csv
(1) Une exprience fournit un fichier texte constitu dune ligne de titre, suivie de lignes, chaque
ligne constitue de 10 nombres rels spars par des virgules. crire une fonction qui lit ce
fichier et qui retourne la liste des lignes du fichier, chaque ligne tant convertie en une liste
de 10 nombres rels.
#ux, uy, uz, tx, ty, tz, wx, wy, wz, d
1.0, 2.0, 3.0, -1.0, 0.0, 1.0, 1.0, 0.5, 0.4, 7.2
etc...
(2) Mme chose, mais des enregistrements peuvent tre vides, comme celui-ci :
, ,, -1.0, 0.0, 1.0, 1.0, 0.5,, 7.2
(3) Mme chose, en ne lisant que les colonnes wx, wy, wz
Exercice 39. Instanciation dynamique
Reprendre le script de lexercice prcdent, et modifiez le afin que les entres du dictionnaire
cr soit instancies comme variables dans un session Python. La fonction execfile() permet
dexcuter un script Python depuis une session Python.
Exercice 40. Dictionnaires
La commande Unix :
$ ls -l >list.txt
permet de lister tous les fichiers du rpertoire courant et de sauvegarder le rsultat dans le fichier
list.txt.
(1) crire linstruction qui permet de lancer cette commande Unix depuis Python ;
(2) relire le fichier list.txt pour crer un dictionnaire dont les cls sont les noms des fichiers
du rpertoire courant, et dont les champs sont la taille de ces fichiers.
Exercice 41. Ensembles
(1) Soit L une liste. Supprimez, laide dune seule instruction simple, tous les doublons de L.
Calculer le nombre dlments distincts de L.
(2) Reprendre lexercice prcdent o cette fois L est une liste de chaines de caractres ASCII
(pas de lettres accentues). On considre quune chane doublonne avec une autre si
elle sont identiques sans tenir compte de la casse (par exemple Everest et eVereSt sont
identiques). Supprimez tous les doublons de L.
Exercice 42. Richesse lexicale
Ecrire un script Python nomm rilex.py qui calcule la richesse lexicale dun texte contenu dans
un fichier dont le nom est pass en argument du script. La richesse lexicale dun texte est dfinie
comme le quotient entre le nombre de mots diffrents et le nombre total de mots du texte. Dans
4.8 Solutions des exercices 107
cet exercice, on dfinit la notion de mot comme toute squence de taille suprieure ou gale
quatre, forme exclusivement de caractres alphabtiques (on ne distinguera pas les majuscules
des minuscules).
Exercice 43. Exceptions
Testez les instructions suivantes, quel est le nom de lexception ?
une division par zro :
>>> 2/0
un indice hors tableau :
>>> a=[]
>>> a[2]
assigner une valeur un item dans un tuple :
>>> tuple=(1,2,3,4)
>>> tuple[3]=45
Exercice 44. Exceptions
En utilisant le mcanisme des exceptions, crire une fonction isFile(fichier) qui renvoie
True si le fichier existe, False sinon
Exercice 45. Exceptions
On dispose dune liste L contenant des objets de type vari.
Par exemple L=[1,'3.14',[],(2,5),'hello',{'d' :3,2.145}]. La fonction suivante ex-
trait de L tous les rels pour alimenter et retourner une nouvelle liste P, mais on oublie simplement
le '3.14'
1 def listeDeReels(L) :
2 P=[]
3 for l in L :
4 if type(l) in (int, float, long) :
5 P.append(float(l))
6 return P
Rcrire la fonction pour prendre en compte le cas des nombres sous forme de chanes de
caractres.
Utiliser le mcanisme des exceptions pour obtenir le mme rsultat.
Solutions des exercices
Solution 24 Expression boolenne.
1 >>> n%2==0
108 Chapitre 4. Les types intgrs (builtins)
Solution 26 Builtins
1 >>> type(__builtins__)
2 <type 'dict'>
1 >>> L=dir(__builtins__)
1 >>> L[42]
2 'values'
1 Help on built-in function sum in module __builtin__ :
2 sum(...)
3 sum(sequence[, start]) -> value
4 Returns the sum of a sequence of numbers (NOT strings) plus the
value
5 of parameter 'start' (which defaults to 0). When the sequence
is
6 empty, returns start.
Solution 27 Formatage, table des carrs et des cubes
1 >>> for x in range(1,11) :
2 ... print ('%2d %3d %4d' % (x, x*x, x*x*x))
(Notez quun espace entre chaque colonne a t ajout cause de la faon dont print fonctionne :
elle ajoute toujours des espaces entre ses arguments.)
Solution 28 Transformer une chane de caractre en un flottant.
1 >>> float('3.14')
Solution 29 Lire des rels dans une chane de caractres
1 >>> [float(m) for m in a.split()]
Solution 30 Lecture de complexes dans une chane de caractres
Une solution compacte :
1 >>> C="(1.0, 2.0) (3, 4)\n"
2 >>> [complex(*eval(c)) for c in C.replace(', ',',').split()]
3 [(1+2j), (3+4j)]
linstruction complex(*eval(c)) dans laquelle c est la chane '(3, 4)', se droule ainsi :
4.8 Solutions des exercices 109
eval(c) renvoie le couple dentiers (3, 4)
complex(*(3,4)) quivaut complex(3,4) par dballage darguments, et renvoie le com-
plexe (3+4j)
Solution 31 TODO
Solution 32 La suite dinstruction donne dans lnonc :
ligne 1 : ouvre un fichier .csv (en lecture par dfaut),
lignes 2 4 : lit les lignes e, du fichier sauf la premire F.readlines()[1 :]. Chaque ligne,
e, est nettoye par strip(), et transforme en liste f par split('\\n'). Comme la ligne e ne
contient en principe quun seul \\n, cette tape est inutile, car f est de longueur 1.
Lunique lment de la liste f est ensuite nettoy, puis transform en liste par dcoupage au point-
virgule, chaque lment de la liste est nettoy. On obtient une liste de listes de listes hideuse
ressemblant
1 [
2 [['K2', '8611', 'Pakistan,Chine', 'Karakoram', '']],
3 [['Pumori', '7161', '', '', '']],
4 [['Shishapangma', '8013', '', '', '']],
5 ...,
6 [['Mont Woodall', '246', 'USA', 'Mississippi', '']]
7 ]
Il est probable que lauteur de ces lignes voulait une liste lisible, comme celle qui suit.
1 [['K2', '8611', 'Pakistan,Chine', 'Karakoram', ''],
2 ['Pumori', '7161', '', '', ''],
3 ['Shishapangma', '8013', '', '', ''],
4 ...,
5 ['Mont Woodall', '246', 'USA', 'Mississippi', '']]
Une solution pour lobtenir consiste dcomposer la tche en crivant :
1 >>> A = open('toto.csv').readlines()[1 :]
2 >>> B = [s.strip('\n ;') for s in A]
3 >>> C = [s.split(';') for s in B if s]
Lassemblage de la liste C ne retient que les enregistrement non vides grce au if s. Si lon tient
crire une seule instruction on obtient le mme rsultat avec :
1 >>> C = [r.split(';') for r in [r.strip('\n ;') \
2 for r in open('toto.csv').readlines()[1 :] if r] if r]
dont la lisibilit est dplorable !
110 Chapitre 4. Les types intgrs (builtins)
Solution 33 Formatage
1 >>> for a,p in zip(articles,prix) :
2 print ('{0 :10s} : {1 :3d} '.format(a,p))
Solution 34 Chanes, encodage
(1) Il suffit dencoder la chane en utf-8 avec la mthode str.encode(format) puis de lcrire
en binaire dans le fichier xxx.utf8. Rpter la mme opration avec le format ISO 8859-15
et un fichier xxx.iso15.
1 >>> a = 'il vous en cotera 45'
2 >>> f = open('xxx.iso15','wb')
3 >>> f.write(a.encode('ISO 8859-15'))
4 22
5 >>> f.close()
6 >>> f = open('xxx.utf8','wb')
7 >>> f.write(a.encode('utf-8'))
8 25
La mthode write() retourne le nombre doctets crits. On remarque quil nest pas le
mme suivant lencodage choisi. Les caractre et sont cod sur 1 octet en ISO 8859-15
et sur 2 et 3 octets en utf-8. Do la diffrence de 25 22 = 3 octets constate ici.
Les instructions prcdentes peuvent tre crites de manire plus simple. En effet la fonc-
tion builtins open() propose linterface :
1 open(file, mode='r', buffering=-1, encoding=None, errors=None,
2 newline=None, closefd=True)
largument encoding permet de demander lencodage voulu lors de lcriture. On na
plus besoin de coder explicitement la chane de caractres, et le fichier na pas tre ouvert
en criture binaire (mode wb) mais en criture standard (mode w). Les instructions se
simplifient :
1 >>> a = 'il vous en cotera 45'
2 >>> f = open('xxx.iso15','w',encoding='ISO 8859-15')
3 >>> f.write(a)
4 22
5 >>> f.close()
6 >>> f = open('xxx.utf-8','wb',encoding='utf8')
7 >>> f.write(a)
8 25
(2) En utilisant la mthode dcrite ci-dessus, un script nu pourrait scrire :
4.8 Solutions des exercices 111
1 import sys
2 infile,outfile = sys.argv[0], sys.argv[1]
3 s = open(infile).read()
4 open(outfile,'w', encoding='Windows-1252').write(s)
Si on en fait un vrai script Python , y compris prcautions, atermoiements et diverses
mises en garde, on obtient
1 #!/usr/bin/python3.1
2 # -*- coding : utf-8 -*-
3 import sys
4
5 def convertFile(infile, outfile, format='utf8') :
6 try :
7 s = open(infile, encoding='utf8').read()
8 except IOError :
9 print ("Impossible d'ouvrir le fichier {}".format(infile)
)
10 return False
11 try :
12 open(outfile,'w',encoding=format).write(s)
13 except IOError :
14 print ("Impossible d'crire dans le fichier {}".format(
outfile))
15 return False
16 return True
17 if __name__ == '__main__' :
18 if len(sys.argv)!=3 :
19 print('''
20 utf2win.py, pour convertir un fichier utf8 en Windows-1252.
21
22 Nombre d'arguments ({}) invalide. Deux arguments taient
attendus.
23 Usage : $ python3.1 utf2win infile outfile
24 '''.format(len(sys.argv)-1))
25 sys.exit()
26
27 # print (convertFile(sys.argv[1], sys.argv[2], 'ISO 8859-15'))
28 print (convertFile(sys.argv[1], sys.argv[2], 'Windows-1252')
)
Solution 35 TODO
112 Chapitre 4. Les types intgrs (builtins)
Solution 36 Lecture
1 l = [int(mot) for mot in s.split(';') ]
1 l = [int(mot) for mot in s.strip(';').split(';')]
1 l = [int(mot) for mot in s.strip(';').split(';') if int(mot)>0]
Solution 37 Lecture
Ce dictionnaire devra donc avoir la structure suivante :
1 dv = {'M' :[[1, 2, 7, 6], [2, 3, 8, 7]];
2 'z' :(1+2j);
3 'chaine' :'hello'}
Voici un script qui effectue les tches demandes :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import sys,os
4
5 dv={}
6 L = [l.strip() for l in open('vars.oct') if l.strip()]
7 for l in L :
8 if l[0] == '#' : #entete
9 if l.find("# name :")>=0 :
10 nblig = 0
11 nom = l.split()[-1]
12 dv[nom] = []#creation de la cle du dico
13 elif l.find("# type :")>=0 :
14 #typ=l[8 :].strip()
15 typ = l.split(' :')[1].strip()
16 elif l.find('# dimensions :')>=0 :
17 [m,n]=[int(w) for w in l[13 :].strip().split()]
18 print m,n
19 elif l.find('# length :')>=0 :
20 le=int(l[10 :].strip())
21 #dv[nom].append(le)
22 else :continue
23 else :
24 #fin entete, debut donnees
25 if typ=='complex scalar' :
26 xx = [float(r) for r in l.strip('()\n ').split(',')]
4.8 Solutions des exercices 113
27 z = complex(*xx)#conversion en complexe
28 dv[nom] = z#ajout dico
29 elif typ=='string' :
30 dv[nom].append(l.strip())#ajout dico, direct
31 elif l.strip() and typ=='matrix' :# and nblig<m :
32 ligne=[float(a) for a in l.split()]
33 dv[nom].append(ligne)
34
35 for key, value in dv.iteritems() :
36 instruction = key+'='+str(value)
37 exec(instruction)
38 print "%s=%s"%(key,eval(key))
Solution 38 TODO
Solution 39 Instanciation dynamique
Le script suivant effectue les tches demandes :
1
2 for key, value in dv.iteritems() :
3 instruction = key+'='+str(value)
4 exec(instruction)
5 print "%s=%s"%(key,eval(key))
Solution 40 Le script Python suivant rpond la question :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 import os,sys
5
6 os.system('ls -l>list.txt')
7 d={}
8 F=open('list.txt').readlines()[1 :]
9 for f in F :
10 f=f.strip().split()
11 (l,nom)=int(f[4]),f[7].strip()
12 d[nom]=l
13 print(d)
Solution 41 Ensembles
114 Chapitre 4. Les types intgrs (builtins)
(1) Un ensemble peut tre vu comme une liste sans doublon. Il suffit donc de transformer la liste
en ensemble et de compter le nombre dlments :
1 >>> L = list('Anti-Constitutionnellement')
2 >>> set(L)
3 {'A', 'C', 'e', 'i', 'm', '-', 'l', 'o', 'n', 's', 'u', 't'}
4 >>> len(set(L))
5 12
(2) crire une liste en comprehension en appliquant la mthode lower() tous les caractres est
une solution.
1 >>> set([l.lower() for l in L])
2 {'a', 'c', 'e', 'i', 'm', '-', 'l', 'o', 'n', 's', 'u', 't'}
Solution 42 Richesse lexicale
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import sys
4 try :f=sys.argv[1]
5 except IndexError :
6 print(u"Donnez le nom du fichier")
7 exit()
8
9 try : text = open(f).read()
10 except IOError :
11 print (u"Problme de lecture sur le fichier %s"%f)
12 exit()
13 text = unicode(text,"utf-8")
14 text = text.replace('\'',' ')
15 words = [w.strip('.,;!?()').lower() for w in text.split() if len(w
)>3]
16
17 #print u', '.join(sorted(words))
18
19 print len(words),len(set(words))," => ",float(len(set(words)))/len
(words)
Pour appeler ce script, il faut lui passer le nom du fichier analyser. Par exemple :
$ python rilex.py fichier_a_analyser
4.8 Solutions des exercices 115
Lignes 4 7 : sil ny a pas dargument sur la ligne de commande, alors sys.argv[1] nexiste
pas et lexception IndexError et leve. La clause except est alors excute (lignes 6 et 7)
Lignes 8 12 : si la lecture (clause try) lve une exception IOError, alors la clause except
est excute (lignes 11 et 12)
Ligne 13 : le texte lu est encod en utf-8.
Ligne 14 : les apostrophes sont supprimes, remplaces par une espace.
Ligne 15 : le texte est dcoups en mots de plus de 4 caractres, puis les caractres ., ;!?() en
dbut et fin de mot sont supprims, et enfin les mots sont convertis en minuscule. Les mots
sont mis dans le liste words.
Ligne 19 : le nombre de mots est obtenu par len(words), et le nombre de mots distincts par
len(set(words)) puisque les doublons sont limin dans un ensemble (set). On obtient la
richesse lexicale en prenant soin de faire une division relle et non pas entire (laquelle aurait
pour rsultat 0).
Solution 44 Exceptions
1 def isfile(fichier) :
2 try :
3 f=open(fichier,'r')
4 f.close()
5 return True
6 except IoError :
7 return False
Solution 45 Exceptions
Une liste de rels.
Sans le mcanisme des exceptions
1 def isNumber(s) :
2 """Dtermine si une chane de caractres est un nombre"""
3 for c in s :
4 if not c in string.digits+'.' : return
5 return True
6
7 def listeDeReels(L) :
8 P=[]
9 for l in L :
10 if type(l) in (int, float) :
11 P.append(float(l))
12 elif type(l) is str and isNumber(l) :
13 P.append(float(l))
14 return P
116 Chapitre 4. Les types intgrs (builtins)
Avec le mcanisme des exceptions
1 def listeDeReels1(L) :
2 P=[]
3 for l in L :
4 try : P.append(float(l))
5 except (ValueError, TypeError) as err :
6 print (type(err).__name__,' : ',l,' impossible
convertir en rel')
Appel des fonctions
1
2 if __name__ == '__main__' :
3 L=[1,'3.14',[],(2,5),'hello',{'d' :3},2.145]
4 print (isNumber('3.14'))
5 print (listeDeReels(L))
6 print (listeDeReels1(L))
CHAPITRE 5
Fonctions, scripts et modules
Jusquici, nous avons rencontr et utilis de nombreuses fonctions. Dans ce chapitre, nous tu-
dions plus en dtail quelques spcificits Python de la programmation fonctionnelle.
5.1. Fonctions
La syntaxe Python pour la dfinition dune fonction est la suivante :
def <nom de fonction> (<liste de parametres>) :
["""<la documentation>"""]
<instructions>
[return [<valeur de retour>]]
Le mot-cl def annonce la dfinition dune fonction. Il doit tre suivi par le nom de la fonction
et une liste entre parenthses de paramtres formels suivit de deux-points ' :'.
En Python les fonctions sont des objets (au sens de la programmation oriente objets). Les fonc-
tions sont de type function, qui hrite du type object :
1 >>> def f(x) :pass
2 ...
3 >>> type(f)
4 <type 'function'>
5 >>> isinstance(f,object)
6 True
ce titre les fonctions possdent des attributs dits spciaux dont les plus courants sont :
__doc__ la docstring ou None ;
__name__ le nom de la fonction ;
__module__ le nom du module dfinissant la fonction, ou None ;
118 Chapitre 5. Fonctions, scripts et modules
5.1.1. Exemple dtaill. Dans un fichier fibo.py, nous pouvons crer une fonction qui crit
la srie de Fibonacci jusqu une limite quelconque :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import doctest
4 def fib(n) :
5 """
6 Retourne une liste contenant
7 la srie de Fibonacci jusqu' n
8 >>> fib(100)
9
10 """
11 resultat = []
12 a, b = 0, 1
13 while b < n :
14 resultat.append(b)
15 a, b = b, a+b
16 return resultat
17 if __name__ == '__main__' :
18 doctest.testmod()
Les instructions qui forment le corps de la fonction commencent sur la ligne suivant la dclaration,
indente par des espaces. Une chane de documentation de la fonction, ou docstring peut tre
utilise pour expliquer le comportement de la fonction.
Lexcution dune fonction gnre une nouvelle table de symboles, utilise pour les variables
locales de la fonction.
Les vrais paramtres (arguments) dun appel de fonction sont introduits dans la table de symboles
locale de la fonction appele quand elle est appele. Les arguments sont passs en utilisant un
passage par affectation.
Un fonction est un objet Python comme un autre. Il est possible de renommer une fonction :
1 >>> from fibo import fib
2 >>> fib
3 <function object at 10042ed0>
4 >>> f = fib
5 >>> f(100)
6 1 1 2 3 5 8 13 21 34 55 89
La fonction fib() retourne la liste des nombres de Fibonacci infrieurs n.
Une fonction retourne toujours une valeur, ventuellement la valeur None
5.1 Fonctions 119
1 >>> def f(x) : x[1]=3.14
2 >>> print(f([1,2,3]))
3 None
La premire instruction dune fonction, ou dun module, devrait tre la chane de documentation,
ou docstring. Certains outils utilisent les docstrings pour gnrer automatiquement de la docu-
mentation papier, ou pour permettre lutilisateur de naviguer interactivement dans le code. Un
docstring peut stendre sur plusieurs lignes.
Les docstrings sont galement utilises par la fonction help() comme le montre lexemple sui-
vant.
1 >>> def carre(x) :
2 ... """Retourne le carr de son argument."""
3 ... return x*x
4 ...
5 >>> help(carre)
6 Help on function carre in module __main__ :
7 carre(x)
8 Retourne le carr de de son argument
5.1.2. Passage darguments. Les arguments sont passs aux fonctions par affectation, ce
qui signifie que les arguments sont simplement affects des noms locaux ( la fonction).
Pratiquement, ce mode de passage par affectation a les consquences suivantes :
les arguments non modifiables miment le comportement du passage par valeur de C, mais ne
sont pas recopis (gain de temps) ;
les arguments modifiables se comportent comme des arguments passs par rfrence en Cet
ne sont pas recopis non plus.
Attention aux effets de bord, laffectation cre une rfrence sur la valeur affecte (sur largument)
et non pas une copie profonde. Par exemple :
1 >>> def modif(liste) :
2 liste[0] = 3.14
3 >>> l = [1,2,3]
4 >>> modif(l)
5 >>> l
6 [3.14, 2, 3]
La squence dinstructions suivante peut tre droutante et mrite quelques explications :
120 Chapitre 5. Fonctions, scripts et modules
1 >>> def f(x) :
2 ... x = []
3 >>> l = list(range(3))
4 >>> l
5 [0, 1, 2]
6 >>> f(l)
7 >>> l
8 [0, 1, 2]
9 >>> def g(x) :
10 ... x[ :] = []
11 >>> g(l)
12 >>> l
13 []
La fonction f(), avec linstruction x = [], cre une liste vide et affecte le nom x cette liste
vide. Le nom de variable x nest plus associ la liste l, argument de f().
La fonction g(), elle, ne raffecte pas le nom x de son argument une autre liste, mais modifie
directement la valeur de x, cest dire la valeur de largument cest dire la valeur de l.
Il est possible de dfinir des fonctions nombre darguments variable. Il y a plusieurs faons de
faire, qui peuvent tre combines.
Valeurs dargument par dfaut. La technique la plus utile consiste spcifier une valeur par
dfaut pour un ou plusieurs arguments. Cela cre une fonction qui peut tre appele avec moins
darguments quil nen a t dfini. Les arguments par dfaut doivent tre les derniers de la liste
darguments. Par exemple, si lon dfinit la fonction suivante :
1 def interrogatoire(nom, prenom='', presume='coupable') :
2 print("Bonjour, monsieur ",nom, prenom )
3 print("Vous tes prsum ", presume)
Cette fonction peut tre appele soit en utilisant une ou des valeurs par dfaut :
1 >>> interrogatoire('Puiseux')
2 Bonjour, monsieur Puiseux
3 Vous tes prsum coupable
ou en prcisant la valeur de certains arguments :
1 >>> interrogatoire('Puissant','','innocent')
2 Bonjour, monsieur Puissant
3 Vous tes prsum innocent
5.1 Fonctions 121
Si une valeur par dfaut est de type modifiable, les effets de bord peuvent tre difficile dceler.
Dans lexemple suivant, la valeur par dfaut est une liste (modifiable) :
1 >>> def f(l=[0,0]) :
2 ... l[0] += 1
3 ... return l
4 >>> f()
5 [1, 0]
6 >>> f()
7 [2, 0]
8 >>> f([0,0])
9 [1, 0]
Largument par dfaut l=[0, 0] est cr lorsque la fonction f() est compile. La fonction nest
compile quune fois, la liste nest donc pas recre entre les diffrents appels, et la liste reste en
ltat entre les diffrents appels. Aprs le premier appel elle vaut donc [1,0], tat quelle conserve
jusquau second appel lors duquel elle passe ltat [2,0]. Lorsque la fonction est appel avec
un paramtre, la valeur par dfaut nest pas modifie, cest le paramtre effectif qui est modifi.
Arguments mot-cl (ou avec tiquettes). Les fonctions peuvent aussi tre appeles en uti-
lisant des arguments mots-cls de la forme motcle=valeur. Dans ce cas, lordre des arguments
peut tre modifi. Par exemple, la fonction prcdente peut tre appele ainsi :
1 >>> interrogatoire(prenom='Pierre', presume='innocent', nom='
Puiseux')
2 Bonjour, monsieur Puiseux Pierre
3 Vous tes prsum innocent
Listes arbitraire darguments. Il est galement possible de spcifier un nombre arbitraire
darguments. Ces arguments seront rcuprs dans un tuple. Avant le nombre variable dargu-
ments, des arguments normaux peuvent tre prsents.
Dans cet exemple, le tuple est X, et *X est le tuple dpaquet ou dball
1 >>> def f(*X) :
2 ... for x in X : print(x, end=' ')
3 >>> f(1,2,3)
4 1 2 3
Arguments dans un dictionnaire. Les arguments de la fonction peuvent tre quelconques. Ils
doivent tre nomms au moment de lappel comme pour une liste darguments mots-cl. Lors
dun appel, Python passe en argument la fonction un dictionnaire dont les cls sont les noms
des arguments nomms. La fonction est appele avec une liste darguments comme une fonction
ordinaire. Par exemple :
122 Chapitre 5. Fonctions, scripts et modules
1 >>> def f(**D) :
2 ... for key, val in D.items() :
3 ... print(key, ' : ', type(val), val)
4 >>> f(a='Zorro', b=3.14, c=[1,2])
5 a : <class 'str'> Zorro
6 c : <class 'list'> [1, 2]
7 b : <class 'float'> 3.14
8 >>> f(L=[], F=0.1, I=1953)
9 I : <class 'int'> 1953
10 L : <class 'list'> []
11 F : <class 'float'> 0.1
Avant largument dictionnaire, dautres arguments ou mme une liste arbitraire darguments (*X)
peuvent tre prsents. Dans lexemple qui suit, dans la porte de la fonction f(), largument L
est un tuple, et largument et D est un dictionnaire :
1 >>> def f(p, *L, **D) :
2 ... print(p, L, D, sep='\n')
3 >>> f(0, 1, 2, Paul=1980, Jean=1979)
4 0
5 (1, 2)
6 {'Paul' : 1980, 'Jean' : 1979}
5.1.3. Les formes lambda. Elles sont une manire dcrire des fonctions la vole, sans
avoir besoin de passer par une instruction def
Pour dfinir une fonction sous forme lambda, on utilise la syntaxe :
1 lambda param1,param2, ... : une_instruction_unique
Par exemple, dans linstruction suivante on dfinit une fonction qui fait la somme de deux variable
x et y et on lapplique au couple (1,3).
1 >>> (lambda x, y : x+y)(1,3)
2 4
fabrique_incrementeur cre et retourne une nouvelle fonction qui incrmente son argument
partir de n :
1 >>> def metaMultiplication(n) :
2 ... return lambda x, mult=n : x*mult
3 ...
4 >>> M3 = metaMultiplication(3) #c'est une fonction
5.2 Rgles de porte 123
5 >>> M3(5)
6 15
Attention ne pas en abuser, car les formes lambda sont un excellent moyen dcrire des pro-
grammes abstrus. On trouve dans la faq de la documentation Python cet exemple qui est suppos
calculer un ensemble de Mandelbrot.
1 print(lambda Ru,Ro,Iu,Io,IM,Sx,Sy :reduce(lambda x,y :x+y,map(
lambda y,
2 Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,
i=IM,
3 Sx=Sx,Sy=Sy :reduce(lambda x,y :x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru
,Ro=Ro,
4 i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f :(k<=0)or (x
*x+y*y
5 >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f) :f(xc,yc,x,y,k,f)
:chr(
6 64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))) :L(Iu+y*(Io-Iu)/Sy),
range(Sy
7 ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
8 # \___ ___/ \___ ___/ | | |__ lines on screen
9 # V V | |______ columns on screen
10 # | | |__________ maximum of "iterations"
11 # | |_________________ range on y axis
12 # |____________________________ range on x axis
5.2. Rgles de porte
5.2.1. Espace de noms. Un espace de noms (name space) est une relation entre des noms et
des objets. Par exemple :
Lespace de noms appel __builtin__ contient lensemble des noms intgrs (les fonctions
telles que abs(), et les noms dexception intgrs). Il est cr au lancement de linterprteur
Python, et nest jamais effac.
Lespace de noms global pour un module contient les noms globaux dfinis par le module. Il
est cr quand la dfinition du module est charge. Les instructions excutes linvocation
de linterprteur font partie dun module appel __main__, elles ont donc leur propre espace
de noms global.
Lespace de noms local une fonction, contient les noms locaux au cours dun appel de fonc-
tion. Il est cr quand celle-ci est appele et il est effac quand la fonction se termine.
124 Chapitre 5. Fonctions, scripts et modules
il ny a absolument aucune relation entre les noms contenus dans les
diffrents espaces de noms.
par exemple, deux modules diffrents (disons truc et troc peuvent dfinir tous les deux une
fonction maximise() sans confusion possible les utilisateurs des modules doivent prfixer par le
nom du module lutilisation : truc.maximise() et troc.maximise()
5.2.2. Porte, la rgle LGI. Une porte (scope) est une rgion textuelle dun programme
Python dans laquelle un espace de noms est directement accessible. A nimporte quel moment
de lexcution, exactement trois portes imbriques sont utilises (exactement trois espaces de
noms sont accessibles directement, rgle LGI) :
(1) la porte locale, qui est explore en premier, contient les noms locaux,
(2) la porte globale, explore ensuite, contient les noms globaux du module courant, et
(3) la porte interne (explore en dernier) correspond lespace de noms contenant les noms
intgrs.
Si un nom est dclar global alors les rfrences et affectations le concernant sont directement
adresses la porte qui contient les noms globaux du module.
Chaque fonction dfinit son propre espace de noms (namespace). Une variable dclare dans
une fonction est inaccessible en dehors de la fonction. Elle appartient lespace de noms de la
fonction.
On ne peut pas affecter directement une valeur aux variables globales depuis lintrieur dune
fonction ( moins de les dclarer avec une instruction global), bien quon puisse y faire rfrence.
Voici un exemple de variable x non globale :
1 >>> def f() :
2 ... x=12
3 ...
4 x = 1
5 >>> f()
6 >>> x
7 1
et un exemple de variable x globale :
1 >>> def f() :
2 ... global x
3 ... x=12
4 ...
5 >>> x = 0
6 >>> f()
5.3 Modules et paquetages 125
7 >>> x
8 12
Une fonction dfinie dans un module Python , est accessible partout ailleurs (dans une session
Python ou dans un autre module) condition de limporter laide de linstruction import.
Par exemple, dans un module bidon (fichier bidon.py) vous dfinissez la fonction :
def f(x) : print('x vaut :',x)
En ligne de commande vous pouvez lutiliser ainsi :
1 >>> import bidon,math
2 >>> bidon.f(math.pi)
5.3. Modules et paquetages
5.3.1. Modules.
les instructions import, from. Un module est associ un fichier avec lextension .py. Le
module porte le nom du fichier et peut contenir des dfinitions de fonction, de variables ou de
classe, aussi bien que des instructions excutables. Ces instructions sont destines initialiser le
module et ne sont excute quune seule fois la premire importation du module.
Chaque module possde sa propre table de symboles prive.
On peut accder aux variables globales dun module avec la mme notation que celle employe
pour se rfrer ses fonctions : nommodule.nomvariable.
Les noms du module import sont placs dans la table globale de symboles du module importa-
teur.
Pour importer et utiliser un module :
1 >>> import random, math
2 >>> random.randint(0,10)
3 >>> math.pi
On peut aussi importer un (ou des) nom(s) particulier(s) dun module. Dans ce cas, ces lment
sont directement rfrencs par leur nom : randint, choice sans quil soit ncessaire de les
prfixer par le nom du module comme ci-dessous :
1 >>> from random import (randint,choice)
2 >>> randint(0,10)
3 >>> choice(range(100))
On peut donner un alias au nom du module :
126 Chapitre 5. Fonctions, scripts et modules
1 >>> import random as rand
2 >>> rand.randint(1, 10)
Il y a une variante pour importer tous les noms dun module, except ceux qui commencent par
un tiret-bas (dconseill) :
1 >>> from random import *
2 >>> choice(500)
La fonction reload(). Dans une session Python , la premire fois quun module est import
par linstruction import module ou from module import x,y, le module est compil ( moins
quun fichier bytecode module.pyc dont la date de dernire modification est plus rcente que
celle du fichier module.py ne soit prsent dans le mme rpertoire). Si une autre instruction
import module est rencontre au cours de la mme session, le module nest pas recompil.
Bien souvent, en cours de dveloppement, le module module.py est modifi. Dans la session
Python , le re-importer pour prendre en compte ces modifications est sans effet puisquil nest
pas recompil. Il faut alors utiliser la fonction reload(module) ce qui a pour effet de compiler
et re-importer module.
Ce faisant, les attributs imports individuellement par from module import x,y ne seront pas
mis jour. Puisque cette instruction nest quune affectation des objets x et y de module aux
noms x et y, dans lespace de nommage __main__. Ces deux objets nont pas t modifis par le
reload() et sont toujours rfrencs sous le nom __main__.x et __main__.y. Il faut donc les
r-importer par from module import x,y. Les noms __main__.x et __main__.y seront alors
mis en correspondance avec les nouveaux objets module.x et module.y . Cet exemple illustre
ces diffrents points :
1 >>> import module
2 >>> dir(module)
3 ['__builtins__', ..., 'parfait', 'sqrt']
4 >>> module.parfait
5 <function parfait at 0xa439924>
6 >>> from module import parfait
7 >>> parfait
8 <function parfait at 0xa439924>
9 >>> reload(module)
10 <module 'module' from './module.pyc'>
11 >>> module.parfait
12 <function parfait at 0xa439bc4>
13 >>> parfait
14 <function parfait at 0xa439924>
15 >>> from module import parfait
16 >>> parfait
5.3 Modules et paquetages 127
17 <function parfait at 0xa439bc4>
1 3 : importation de module, qui contient une fonction parfait ;
4, 5 : la fonction parfait est ladresse ..924 ;
6 : la fonction module.parfait est affecte au nom __main__.parfait ;
7, 8 : son adresse est donc celle de module.parfait ;
9, 10 : compilation et importation de module.py ;
11, 12 : la fonction module.parfait est un nouvel objet, avec une nouvelle adresse ..bc4 ;
13, 14 : la fonction pointe par le nom __main__.parfait est toujours la mme (ancienne)
adresse ..924 ;
15 17 : le nom __main__.parfait est raffect au (nouvel) objet module.parfait la nou-
velle adresse, lancien parfait est dtruit
5.3.2. Paquetages. Un paquetage Python est une arborescence de paquetages et de modules.
Un paquetage possde un rpertoire racine dans lequel se trouve un fichier __init__.py. Usuel-
lement un paquetage possde une unit et un cohrence interne, mais rien nempche un paque-
tage Python de contenir cte cte une base de donnes de recette de cuisines et une bibliothque
de fonctions mathmatiques.
Un paquetage peut se charger comme un module par linstruction
1 >>> import paquetage
Dans ce cas on accde aux modules du paquetage par la notation usuelle paquetage.module.
Le fichier __init__.py du paquetage, qui se trouve la racine du rpertoire-paquetage, est un
fichier script Python ordinaire excut au chargement du paquetage, dans lequel sont faites di-
verses initialisations concernant le paquetage. On peut y trouver en particulier une liste
1 __all__=[mod1,mod2,...,var1,var2,...]
qui sera utilise lors de linstruction
1 >>> from paquetage import *
mod1,mod2, ... sont des noms de modules, var1, var2, ... sont des noms de variables.
Rien nempche cependant dimporter un module existant qui nest pas list dans __all__ par
une instruction explicite
1 >>> from paquetage import module_non_liste
128 Chapitre 5. Fonctions, scripts et modules
5.3.3. Le chemin de recherche des paquetages et modules. Quand un module nomm
spam est import, linterprteur recherche un fichier nomm spam.py
dans le rpertoire courant, et puis
dans la liste de rpertoires indique par la variable denvironnement PYTHONPATH.
dans un chemin daccs par dfaut, dpendant de linstallation ; sur Unix, cest habituellement
/usr/local/lib/python.
En fait, les modules sont recherchs dans la liste de rpertoires donne par la variable sys.path.
Ainsi, si votre module karakoram se trouve dans un rpertoire exotique, disons /home/pui-
seux/vacances/pakistan, il vous suffit dajouter le nom de ce rpertoire la liste sys.path :
1 >>> import sys
2 >>> sys.path.append('/home/puiseux/vacances/pakistan')
3 >>> import karakoram
5.3.4. Fichiers bytecode. Pour acclrer le temps de lancement, si un fichier appel spam.pyc
existe dans le rpertoire o se trouve spam.py, il est suppos contenir une version du module spam
dj compile en bytecode.
Au lancement de spam.py
recherche de spam.pyc (fichier dj compil en bytecode) dans le mme rpertoire que spam.py.
si spam.pyc existe, et si sa date de cration est postrieur celle de spam.py, alors il est
lanc.
sinon, spam.py est compil et spam.pyc est excut
Toutes les fois que spam.py est compil avec succs, une tentative est faite pour crire la version
compile sur spam.pyc.
Le contenu du fichier spam.pyc est indpendant de la plate-forme, ainsi un rpertoire de module
de Python . Il peut tre partag par des machines darchitectures diffrentes.
5.3.5. Modules standard. Python est livr avec une bibliothque de modules standard, d-
crite dans un document spar, Python Library Reference. Cette bibliothque sera examine plus
en dtail au chapitre 7. Quelques modules standard de base :
math : fonctions et constantes mathmatiques de base (sin, cos, exp, pi...).
sys : passage darguments, gestion de lentre/sortie standard...
os : dialogue avec le systme dexploitation (e.g. permet de sortir de Python , lancer une
commande en shell, puis de revenir Python ).
random : gnration de nombres alatoires.
time : permet daccder lheure de lordinateur et aux fonctions grant le temps.
calendar : fonctions de calendrier.
profile : permet dvaluer le temps dexcution de chaque fonction dans un programme
(profilage ou profiling en anglais).
5.4 Dcorateurs 129
urllib2 : permet de rcuprer des donnes sur internet depuis Python .
Tkinter : interface python avec Tk (permet de crer des objets graphiques ; ncessite dins-
taller Tk).
re : gestion des expressions rgulires.
pickle : criture et lecture de structures Python (comme les dictionnaires par exemple).
doctest : un module pour le dveloppement dirig par la documentation, cest dire per-
mettant dcrire en mme temps les tests et la documentation voir 2.12 page 45.
5.4. Dcorateurs
Un dcorateur Python est une fonction qui prend en paramtre une autre fonction, pour la modi-
fier, lui ajouter des fonctionnalits, la substituer ou simplement excuter un travail avant ou aprs
lavoir appel.
Un dcorateur nomm monDecorateur() est appel en plaant linstruction @monDecorateur
au dessus de la fonction cible.
Un exemple de dcorateur pour rendre la comparaison de deux chanes de caractres insensible
la casse :
1 def caseInsensitive(func) :
2 def minuscule(x) :
3 return func(*[a.lower() for a in x])
4
5 @caseInsensitive
6 def isEqual(x, y) :
7 return (x == y)
Comparons les chanes de caractres ChomoLunga et chomolunga :
1 >>> isEqual("ChomoLunga","chomolunga")
2 True
Voici un deuxime exemple de dcorateur, totalement inutile, mais illustrant bien le fonctionne-
ment :
1 def monDecorateur(f) :
2 def _monDecorateur() :
3 print("decorator stuff")
4 f()
5 print("other stuff")
6 return
7 return _monDecorateur
8
9 @monDecorateur
130 Chapitre 5. Fonctions, scripts et modules
10 def cible() :
11 print ("fonction stuff")
et lorsque lon appelle la fonction cible(), son comportement a t modifi par le dcorateur :
1 >>> cible()
2 decorator stuff
3 fonction stuff
4 other stuff
Comme on le remarque sur cet exemple, ds quon applique un dcorateur sur une fonction celui-
ci prend le contrle, et peut mme compltement ignorer la fonction cible().
En termes mathmatiques, la fonction f dcore par la fonction g est la fonction g f
5.5. Fonctions intgres, le module __builtin__
Contient les fonctions intgres (builtins) et les exceptions. Les fonctions builtins sont codes
en dur dans linterprteur Python et aucun import nest ncessaire pour y accder. Quelques
unes ont t prsentes dans les sections prcdentes .
Une liste complte (environ 68 fonctions) et documente des fonctions intgres se trouve sur
http://docs.python.org/library/functions.html.
On prsente ici les plus courantes.
5.5.1. Manipulation dattributs. Un attribut dun objet est une valeur associe cet objet,
rfrence par son nom, via une expression pointe . Par exemple math.pi est lattribut pi du
module math.
Tous les objets Python ont des attributs.
Les attributs de classe seront dcrits au chapitre 6 page 153.
Les fonctions suivantes permettent de manipuler ces attributs.
hasattr(object, attr) retourne True ou False selon que lobjet Python object possde
ou non un attribut nomm attr.
getattr(object, name[, default]) retourne lattribut name de lobjet object. Si lat-
tribut nexiste pas, une exception AttributeException est leve. Lexpression getattr(X
, 'a') quivaut X.a. Le paramtre name est une chane de caractres.
delattr(object, name) supprime lattribut name de lobjet object. Si lattribut nexiste
pas, une exception AttributeException est leve. Lexpression delattr(X,'a') quivaut
delX.a
setattr(object, name, value) ajoute un attribut name de valeur value lobjet object.
Lexpression setattr(X,'a',v) quivaut X.a = v.
Voici un exemple utilisant ces fonctions :
5.5 Fonctions intgres, le module __builtin__ 131
1 >>> class A : pass
2 ...
3 >>> a = A()
4 >>> setattr(a,'x',1)
5 >>> hasattr(a,'x')
6 True
7 >>> delattr(a,'y')
8 Traceback (most recent call last) :
9 [...]
10 AttributeError : A instance has no attribute 'y'
11 >>> delattr(a,'x')
12 >>> dir(a)
13 ['__doc__', '__module__']
Il est possible dajouter des attributs la plupart des objets Python . Par exemple :
1 >>> import math
2 >>> math.toto = 7
3 >>> hasattr(math, 'toto')
4 True
5 >>> math.toto
6 7
5.5.2. Conversion de type, construction. De nombreuses fonctions intgres permettent la
conversion dun type un autre. On peut distinguer les constructeurs, qui sont des fonctions de
mme nom que le type instance, et les fonctions de conversion proprement dit. Les principaux
constructeurs ont dj t voqus au chapitre 4 page 79.
Les autres fonctions intgres de conversion sont :
hex(i) convertit un nombre entier en chane hexadcimale.
oct(x) convertit un nombre entier en chane octale.
chr(i) retourne le caractre dont le code Unicode est lentier i. Par exemple, chr(97) re-
tourne 'a'. Largument i doit tre compris dans lintervalle [0, 1114111].
ord(c) est linverse de la fonction chr(). Retourne le code Unicode (Unicode code point
dans la terminologie Unicode) de largument, qui doit tre un caractre Unicode.
Exemple :
1 >>> for i in range(34,50) :
2 ... print(chr(i),end=' ')
3 " # $ % & ' ( ) * + , - . / 0 1
4
132 Chapitre 5. Fonctions, scripts et modules
5 >>> for c in string.ascii_lowercase :
6 ... print ('ord({0})={1}'.format(c,ord(c)),end=' ; ')
7
8 ord(a)=97 ; ord(b)=98 ; ord(c)=99 ; [...] ; ord(z)=122 ;
5.5.3. Logique.
all(iterable) retourne True si tous les lments de litrable sont vrais et False sinon.
any(iterable) retourne True sil existe un item vrai dans iterable, False sinon.
callable(object) ( partir de Python 3.2) retourne True si object est appelable (essen-
tiellement une fonction, mthode ou classe, partir de Python 3.2).
1 >>> all(range(12))
2 False
3 >>> all(range(1,12))
4 True
5 >>> any(range(1))
6 False
7 >>> any(range(2))
8 True
5.5.4. Programmation.
compile(source, filename, mode) retourne la chane source compile en objet code
qui peut-tre excut par eval() ou exec(). Dautres paramtres sont disponibles, voir la
documentation Python .
filename est le nom du fichier o source a t lu. Si source nest pas lire sur un
fichier, mettre filename='<string>'.
mode prendra une des valeurs 'exec' si source est une suite dinstructions, ou bien
'eval' sil sagit dune simple expression ou encore 'single' sil sagit dune instruc-
tion interactive comme laffichage dune valeur.
eval(expression, globals=None, locals=None) value une expression. Les arguments
sont une chane de caractre (expression) , et deux dictionnaires (globals et locals). Lar-
gument expression est valu comme une expression Python en utilisant les dictionnaires
globals et locals comme espaces de nommage global et local. La valeur de retour est le
rsultat de lvaluation. Exemple :
1 >>> x = 1
2 >>> print (eval('x+1'))
3 2
Cette fonction peut galement tre utilise pour excuter des codes arbitraire comme ceux
crs par compile(). Dans ce cas, expression doit-tre un objet code.
5.5 Fonctions intgres, le module __builtin__ 133
exec(object, globals=None, locals=None)
1
excute une instruction ou une liste dins-
tructions. Le paramtre object doit tre une chane de caractres reprsentant la suite dins-
tructions, ou bien un objet code (comme produit par compile()). Les paramtres globals et
locals ont le mme rle que pour la fonction eval(). La fonction exec() na pas de valeur
de retour. Exemple, comparaison exec() versus eval() :
1 >>> exec('x = 5')
2 >>> exec('x = 5\n print(x)')
3 5
4 >>> eval('x = 5')
5 Traceback (most recent call last) :
6 [...]
7 x = 5
8 ^
9 SyntaxError : invalid syntax
10 >>> eval('5+2')
11 7
locals() met jour et retourne un dictionnaire reprsentant le table des symboles locale.
globals() retourne un dictionnaire reprsentant la table des symboles courante, cest dire
le dictionnaire du module courant. lintrieur dune fonction ou dune mthode, il sagit du
module dfinissant la fonction, et non pas le module appelant.
5.5.5. Itrables. Une des principales diffrence entre Python 2 et Python 3 tient au mode
de gestion des itrables. Grosso-modo, lorsquen Python 2 une squence (liste, tuple, ...) est
retourne, en Python 3 cest un itrateur qui est renvoy. La diffrence en terme dencombrement
est vidente puisque dans le premier cas, une squence entire est cre et stocke, tandis quen
Python 3, les termes de litrable sont calculs et fournis au fur et mesure de la demande, sans
tre stocks. Par exemple pour une liste et un itrateur de 10
7
entiers lencombrement est donn
par :
1 >>> import sys
2 >>> sys.getsizeof(range(10000000))
3 20
4 >>> sys.getsizeof(list(range(10000000)))
5 45000056
Par contre en terme de temps dexcution, les deux approches (liste/itrateur) ne sont pas trs
diffrentes :
1
La fonction exec() remplace linstruction exec et la fonction execfile() de Python 2. Cette dernire nexiste
plus en Python 3
134 Chapitre 5. Fonctions, scripts et modules
1 >>> import profile
2 >>> profile.run("for i in range(10000000) : i*i")
3 4 function calls in 2.636 CPU seconds
4 [...]
5 >>> profile.run("for i in list(range(10000000)) : i*i")
6 4 function calls in 2.648 CPU seconds
7 [...]
enumerate(iterable, start=0) retourne un objet de type enumerate. Largument iterable
doit tre une squence, un itrateur, ou tout autre objet supportant litration. Cette fonction
et utilise essentiellement pour obtenir une srie index : (0, seq[0]), (1, seq[1]), (2,
seq[2]), etc.. Exemple :
1 >>> notes = ['mi','la','r','sol','si','mi']
2 >>> for i,note in enumerate(notes) :
3 ... print ('Corde numro {} : {}'.format(i+1,note))
4 Corde numro 1 : mi
5 Corde numro 2 : la
6 Corde numro 3 : r
7 Corde numro 4 : sol
8 Corde numro 5 : si
9 Corde numro 6 : mi
filter(function, iterable) construit un itrateur sur les items de iterable pour les-
quels la fonction function retourne True. Largument iterable peut tre une squence, un
conteneur supportant les itrations, ou un itrateur. Si function vaut None, elle est suppose
gale lidentit, tous les lments faux de iterable sont supprims.
map(function, iterable, ...) retourne un itrateur qui applique function tous les
termes de iterable. Si plusieurs nitrables sont passs en arguments, la fonction doit prendre
n arguments. Litrateur stoppe lorsque litrable le plus court a t entirement parcouru.
2
max(iterable[, args...][, key]) avec le seul argument iterable (de type itrable),
retourne le plus grand de ses items. Avec plusieurs arguments, retourne le plus grand des
arguments. Largument optionnel key est une fonction un argument applique chaque item
avant le tri qui dtermine le max. Autrement dit, max() calcule le maximum de la squence
[key(i)for i in iterable], disons key(it0) et retourne it0.
2
En Python 2, map(function, iterable, ...) applique function tous les items de iterable et en retourne
la liste. Si la liste darguments contient dautres itrables, alors function les traite en parallle. Si un itrable est
plus court que les autres, il est complt par None autant de fois que ncessaire. Si function vaut None, elle est
remplace par lidentit. La fonction map() renvoie une liste de tuples, la longueur de chaque tuple est gale au
nombre ditrables passs en arguments.
5.5 Fonctions intgres, le module __builtin__ 135
min(iterable[, args...][, key]) avec le seul argument iterable (de type itrable),
retourne le plus petit de ses items. Avec plusieurs arguments, retourne le plus petit des ar-
guments. Largument optionnel key fonctionne de manire analogue largument key de la
fonction max()
next(iterator[, default]) retourne litem suivant de iterator par appel sa mthode
next(). Largument iterator doit tre de type itrateur. Si largument default est prsent,
il est retourn lorsque litrateur est puis. Sinon lexception StopIteration est leve.
range(start=0, stop, step=1) permet la cration de progressions arithmtiques itrables.
Voir 3.5 page 65
reversed(seq) retourne un itrateur inverse (reverse iterator). Largument seq doit tre
un objet possdant une mthode __reversed__() ou bien supportant le protocole des s-
quences (cest dire possdant une mthode __len__() et une mthode __getitem__()
avec argument dans N).
sorted(iterable[, key][, reverse]) retourne une nouvelle liste trie, partir des items
de litrable. Les deux arguments key et reverse sont optionnels. Si key est prsent, ce
doit tre une fonction un seul argument destine tre applique tous les lments avant
comparaison (typiquement, key=str.lower transformera toutes les chanes en minuscule
avant de les trier). Si reverse vaut True, le tri se fera en ordre inverse. La valeur par dfaut
de reverse est False.
zip(*iterables) retourne un itrateur dont les lments sont des tuples. Le i-me tuple est
constitu des i-mes lments de chacun des itrables passs en argument. Si les itrables
nont pas la mme longueur, litrateur retourn a la longueur du plus court des itrables.
5.5.6. Entres-sorties.
format(value[, format_spec]) . Cette fonction a t dcrite 4.5.6 page 96
input([prompt]) affiche prompt lcran et se met en attente dune rponse de lutilisateur.
La rponse est retourne par la fonction sous forme de chane de caractres. La chane de
caractres ne doit pas tre mise entre guillemets. Pour obtenir autre chose quune chane de
caractres, il faut le convertir explicitement.
3
1 >>> nomfichier = input("nom de fichier ? ")
2 nom de fichier ? toto.txt
3 >>> print(nomfichier)
4 'toto.txt'
5 >>> age = int(input("Age du capitaine ? "))
6 Age du capitaine ? 40
3
Python 2 propose deux fonctions de saisie :
la fonction raw_input([prompt]) qui se comporte comme a fonction input() de Python 3 en retournant
une chane de caractre et
la fonction input() est quivalente eval(raw_input()). Elle attend une expression Python syntaxiquement
correcte.
136 Chapitre 5. Fonctions, scripts et modules
open(file, mode='r', encoding=None, buffering=-1) Ouvre un fichier et retourne
le flux correspondant. Si le fichier ne peut pas tre ouvert, lexception IOError est leve.
file est soit une chane de caractres donnant le chemin du fichier (chemin absolu ou
relatif au rpertoire courant), soit un descripteur de fichier
4
.
mode est une chane de caractres optionnelle spcifiant le mode douverture du fichier,
contenant un ou plusieurs caractres spcifis dans le tableau suivant. Sa valeur par d-
fault est 'rt', le fichier est ouvert en lecture et en mode texte. En mode texte, si le
paramtre encoding nest pas spcifi, le mode dencodage utilis dpend de la plate-
forme.
Caractre Signification
'r' Lecture
'w' criture
'a' Ajout
'b' Binaire
't' Texte
'+' Mise jour (lecture et criture)
Tab. 1. Modes douverture dun fichier
Un fichier ouvert en mode binaire (mode='b') retourne son contenu sous forme doctets,
sans dcodage. Un fichier ouvert en mode texte (mode='t') retourne son contenu sous
forme de chane de caractres (str) aprs un dcodage utilisant le mode spcifi par
largument encoding.
encoding Les principaux encodage pour lEurope de louest sont 'ascii', 'cp1252',
'latin_1', 'utf_8', etc., avec des alias possible. Une liste complte des encodages dis-
ponible est donne dans http://docs.python.org/py3k/library/codecs.html#standard-encodings.
buffering=-1 est un entier (optionnel) , indiquant la stratgie de buffering (mise en
mmoire tampon) adopter. Utile pour les gros fichiers, la valeur 0 dsactive le buffering,
le fichier entier est lu en une seule passe (autoris en mode binaire seulement). La valeur
1 demande un buffering (mode texte seulement) et un entier suprieur 1 fixe la taille
du buffer. Par dfaut les fichier binaires sont bufferiss, la taille du buffer dpend du
systme (typiquement 4096 ou 8192 octets). En mode texte, la taille du buffer est une
ligne.
Dautres arguments sont disponibles :
errors=None pour prciser la stratgie de gestion des erreurs,
newline=None pour la gestion des fins de lignes,
closefd=True
consulter la documentation Python pour plus de prcisions.
4
Un descripteur de fichier est un entier. Si f est un fichier ouvert, la mthode f.fileno() retourne son descripteur.
5.5 Fonctions intgres, le module __builtin__ 137
5.5.7. Classes.
isinstance(object, classinfo) retourne True si largument object est une instance
de classinfo ou dune classe fille. classinfo doit tre une classe, un type ou un tuple de
classes ou de types. Sinon, une exception TypeError est leve.
issubclass(class, classinfo) retourne True si class est une classe hritant de classinfo
. Une classe est considre comme hritant delle-mme. classinfo peut aussi tre un tuple
de classes. Sinon, une exception TypeError est leve.
5.5.8. Mathmatiques.
divmod(a, b) voir 2.6 page 35.
pow(x, y[, z]) retourne x
y
, quivaut x**y. Si z est prsent, x et y doivent tre entiers, et
y doit tre positif ou nul. Dans ce cas, retourne x la puissance y modulo z calcul de manire
plus efficace que pow(x,y)%z
round(x, n=0) retourne x arrondi n dcimales. Return the floating point value x rounded
to n digits after the decimal point.
abs(x) valeur absolue ou module pour un complexe.
5.5.9. Divers.
id(object) retourne lidentit dun objet : un entier unique tout au long de la vie de
lobjet.
hash(object) retourne la valeur de hachage de lobjet (un entier) si elle existe.
dir(module=None) renvoie une liste des noms dfinis par le module module.
1 >>> import fibo
2 >>> dir(fibo)
Sans arguments, numre les noms dfinis par lutilisateur :
1 >>> a = [1, 2, 3, 4, 5]
2 >>> import fibo, sys
3 >>> fib = fibo.fib
4 >>> dir()
Enumre tous les types de noms : les variables, les modules, les fonctions, etc... sauf les
noms des fonctions et des variables intgres.
5
type(objet) renvoie le type dun objet
len(obj) renvoie la taille dun objet
quit() pour quitter Python
assert(condition) dclenche une exception si la condition est fausse.
5
Linstruction dir(__builtins__) retourne une liste des noms intgrs (exceptions, types, fonctions, ...)
138 Chapitre 5. Fonctions, scripts et modules
1 >>> import os
2 >>> filename='toto.txt'
3 >>> assert(os.path.isfile(filename))
donne le mme rsultat que
1 >>> if not os.path.isfile(filename) :
2 ... raise AssertionError
Exercices
Exercice 46. Navigation dans les modules
(1) Quel est le contenu du module matplotlib ?
(2) Dans quel rpertoire se trouve ce module ?
(3) Trouvez un tutoriel matplotlib et testez les premires instructions.
Exercice 47. Fonctions
Que fait la squence dinstructions suivante ?
1 >>> def echo(msg) :
2 ... print(msg)
3 >>> x = echo
4 >>> x("ca marche")
Exercice 48. Arguments : modifier une liste
(1) Ecrire une fonction modif(L) qui modifie la liste L, en changeant son premier lment en
'change' et qui ne retourne rien.
(2) Ecrire une fonction fidom(L) qui ne modifie pas la liste L, mais qui renvoie une copie de L
dont le premier terme est modifi en 'change'
Exercice 49. Suite de Fibonacci :
crire la fonction fibonacci dans un fichier fibo.py et testez les instructions
1 >>> from fibo import fib, fib2
2 >>> fib(500)
3 >>> import fibo
4 >>> fibo.fib(20)
Exercice 50. Richesse lexicale
Reprendre lexercice 4.8 page 106, et crer les fonctions
5.5 Exercices 139
wordList(text, n) qui retourne une liste des mots du texte pass en argument, tant postul
quun mot comporte au minimum n lettres, n = 3 par dfaut
frequence(words) qui prend en argument une liste de mots, qui retourne un dictionnaire
dont les cls sont les mots utiliss, et les valeurs sont les frquences dapparition des mots.
lexicalRichness(text) qui calcule et retourne la richesse lexicale du texte pass en ar-
gument
wordCount(text, n) qui compte le nombre de mots distincts du texte pass en argument,
attendu quun mot doit comporter au moins n caractres, n = 3 par dfaut.
Exercice 51. Passage darguments
Tester les instructions, interprtez les rsultats :
1 >>> def modif(x) : x[0] += 10
2 ...
3 >>> a = [1,2,3]
4 >>> modif(a)
5 >>> print(a)
6 >>>
7 >>> def fidom(x) : x=0
8 ...
9 b=1
10 >>> fidom(b)
11 >>> print(b)
Exercice 52. Espace de nommage
crire un fichier tests.py contenant ces lignes :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import os
4
5 print ("La variable __name__ vaut : ",__name__)
6
7 def inters(l1,l2) :
8 """Intersection de deux listes"""
9 return list(set(l1)&set(l2))
10
11 if __name__=="__main__" :
12 print (os.listdir('.'))
13 print (inters([1,2,3],[2,3,4]))
140 Chapitre 5. Fonctions, scripts et modules
Dans une session Python , importez le module tests.
Dans un terminal, xecuter le script tests.py.
Interprtez le rsultat.
Exercice 53. Rgles de porte, comment planter Python .
(1) Quelle est la nature de la variable __builtins__ ?
(2) Quelles sont les cls de __builtins__ ?
(3) Que contient __builtins__['max'] ?
(4) Quel est lespace de noms de la fonction max() ?
(5) Que se passe-t-il si lon masque la fonction max(), par exemple avec linstruction
>>> max=0.5 ?
(6) Que se passe-t-il si lon efface __builtins__['max'] ?
(7) Que se passe-t-il si lon efface __builtins__ ?
(8) Que se passe-t-il si lon masque le dictionnaire __builtins__, par exemple avec linstruc-
tion
>>> __builtins__=12 ?
(9) Quadvient-il lorsque lon crit :
>>> def f(x) :global x ?
Exercice 54. Fonctions builtins
(1) Utilisation lmentaire
Voici des notes dtudiants N=[5, 3, 2.5, 7, 0.5, 19]. Calculez le max, le min et
la moyenne de ces notes.
Depuis une session Python , lire le fichier de donne data.txt et crer les quatres
variables a,b,c et d en les initialisant avec les valeurs prcises dans ce fichier.
quelle est la diffrence entre les fonctions exec() et eval() ?
Crez une liste de n nombres entiers alatoires (module random).
(2)
Exercice 55. Rcursivit : somme des chiffres dun nombre entier.
crire une fonction som(S) qui a pour argument S une chane de caractres constitue de chiffres
uniquement, et qui calcule rcursivement la somme des tous ses chiffres jusqu obtenir un r-
sultat un seul chiffre, et le renvoie sous forme de caractre.
Exercice 56. Rcursivit : les tours de Hano
(1) Ecrire une fonction rcursive hanoi(n, depuis, vers, par) qui implmente lalgorithme
clbre des tours de Hano. Voir http://fr.wikipedia.org/wiki/Tours_de_Hanoi
(2) Ajouter un compteur N du nombre de dplacements, afficher le nombre de dplacements en
fin dexcution.
Exercice 57. csv2vcf : lire une feuille Excel au format csv
Un fichier de contacts, contacts.csv, a t export par un tableur ou un gestionnaire de contacts,
au format csv sous la forme :
5.5 Exercices 141
prnom, nom, email, tel, commentaire
(1) dans un premier temps lire ce fichier en Python et en faire un dictionnaire dont les cls sont les
couples (nom, prenom) et les valeurs les tuples (email, tel, commentaire). Attention
aux virgules lintrieur de certains champs.
(2) Sauvegarder les contacts au format vcard, dans un fichier contacts.vcf, une carte par
contact au format suivant :
BEGIN :VCARD
VERSION :3.0
N :puiseux;pierre;;;
FN :pierre puiseux
EMAIL;type=INTERNET;type=HOME;type=pref :[email protected]
TEL;TYPE=CELL :06-89-70-79-94
END :VCARD
Exercice 58. Fichier IGC : lecture dune trace GPS.
Une trace GPS est une suite de points de (t
n
, P
n
) R
+
R
3
reprsentant la trajectoire effectue
par un parapente lors dun vol. Le format IGC est assez simple, et dcrit partiellement en (5.5.9).
Crer un nouveau dossier GPS lintrieur duquel, un module Python nomm lecture (cest
dire un fichier lecture.py) proposera les fonctions suivantes :
(1) une fonction latitude(r) aura comme argument un enregistrement et retournera la latitude
en radians (pour faire ce calcul, on notera que 42 deg 58.954 mn font 42+58.954/60 degrs
dcimaux, que lon transforme facilement en radians en multipliant par
180
),
(2) une fonction longitude(r) aura un comportement analogue,
(3) une fonction altitude(r) retournera laltitude du barographe (en mtres),
(4) une fonction heure(r) retournera lheure sous la forme dune liste dentiers [hh,mm,ss],
(5) une fonction lecture(nomfichier) retournera un tripl (date, modele, points) o
date est lenregistrement contenant la date, modele est lenregistrement contenant le mo-
dle et points est la liste des enregistrements contenant des points GPS,
(6) une fonction distance(a,b,unit='km') retournera la distance entre deux enregistrements-
points. En m ou bien km, suivant la valeur du paramtre unit.
(7) des instructions testant ces fonctionnalits.
Exercice 59. Fichier IGC (suite).
Dans un nouveau module Python , nomm resume, on programmera une fonction resume()
fournissant un rsum du vol sous la forme :
Modle de la voile
Date du vol
Dure du vol
Vitesse moyenne (relle et projete)
Finesse moyenne
6
6
il sagit du rapport distance horizontale/distance verticale
142 Chapitre 5. Fonctions, scripts et modules
Distance parcourue (distance relle et projete)
Dnivel
Pour pouvoir accder aux fonctions du module lecture, il faudra bien sr les importer dans le
module resume.
Exercice 60. Fichier IGC, analyse dtaille (suite).
(1) Une fonction decompose(L) prendra comme argument la liste L retourne par la fonction
lecture() et retournera une liste denregistrements dcompos [heure, latitude, longitude,
altitude]
(2) Une fonction vitesses(D) prendra comme argument la liste D renvoye par fonction decompose
(L) et renverra une liste des vitesses.
(3) Des fonctions altitudes(D), longitude(D), latitudes(D) renverront la liste des alti-
tudes, longitudes et latitudes sur le mme principe.
(4) Une fonction distances(D) renverra la liste des distances parcourues depuis le dpart.
Exercice 61. Dcorateur pour vrification de type.
Prvoir le comportement des instructions suivantes :
1 def ArgEntier(f) :
2 def _ArgEntier(arg) :
3 if not isinstance(arg,int) :
4 raise TypeError("%s : %s n'est pas de type entier" \
5 % (arg,type(arg)))
6 else : return f(arg)
7 return _ArgEntier
8
9 @Entier
10 def h(x) :
11 return x*x
12
13 print(h(1))
14 print(h(1.2))
Exercice 62. Dcorateurs.
Soit la fonction
1 def f(x) : return x*x
(1) Ajouter un dcorateur la fonction f, qui verifie que largument x est de type float et lve
une exception TypeError si a nest pas le cas.
(2) Ajouter un dcorateur la fonction f, qui lve une exception adapte si le nombre dargu-
ments est diffrent de 1
5.5 Exercices 143
Exercice 63. Dcorateur
Soit la fonction def g(x) : print(x).
Ecrire un dcorateur Majuscule, appliquer le g de sorte que :
1 >>> g('hello')
produise le rsultat
1 HELLO
Exercice 64. Profilage
Il sagit dvaluer les performances des list comprehension. Dans un script Python :
(1) crez une grande liste L dentiers alatoires (de taille N = 1000 par exemple) compris dans
lintervalle [100, 100]. Crez galement une fonction
1 def f(x) :
2 return sin(x/2.0)
(2) Crez (et testez) une fonction mapWithoutListComprehension() qui rpte 100 fois le cal-
cul de la liste des f(x) pour x dans L, en utilisant la fonction map(). Cette fonction neffec-
tuera aucune impression ni affectation.
(3) Crez (et testez) une fonction mapWithListComprehension() qui effectue la mme tche
mais avec la technique de list comprehension.
(4) Utiliser la fonction run() du module profile pour comparer les temps dexcution des deux
fonctions.
(5) Conclusion ?
Le format IGC (International Gliding Commission). Un fichier IGC se prsente ainsi :
http://web.univ-pau.fr/~puiseux/enseignement/python/
2010-2011/Chap2-Prog/GPS/test.igc
Dans ces enregistrements (1 ligne = 1 enregistrement), seule nous intresse la srie des enregis-
trements suivants :
HFDTE260309 qui contient la date sous la forme jjmmaa
HFGTYGLIDERTYPE :Kailash bivouac qui dtermine le modle daronef
B+38caractres contient des donnes enregistres intervalles rguliers, toutes les 1 ou 2
secondes. Par exemple, lenregistrement B 084035 4258954N 00002136W A01231 01186
038 (auquel on a rajout des espaces pour plus de lisibilit) se lit ainsi :
084035 est lheure, ici 08h 40mn 35sec
4258954N est la latitude, ici 42 deg 58.954 mn, en degrs, minutes et fraction de minutes
(mais pas en secondes), dans lintervalle [0, 90],
144 Chapitre 5. Fonctions, scripts et modules
00002136W longitude (1 chiffre de plus que pour la latitude, car la longitude est dans
lintervalle [0, 160]),
01231 altitude barographe en mtres, elle est plus prcise que laltitude GPS,
01186 altitude GPS en mtres
038 vitesse calcule par la sonde si elle est prsente
On considre deux points GPS de coordonnes (en radians) M
1
= (x
1
, y
1
). La distance d(M
1
, M
2
)
est donne, en mtres, par la formule
d(M
1
, M
2
) = r arcos (sin(x
1
) sin(x
2
) + cos(x
1
) cos(x
2
) cos(y
2
y
1
))
o r = 6378.7 10
+3
(mtres) est la circonfrence de la terre.
Solutions des exercices
Solution 46 Navigation dans les modules
(1) Contenu du module matplotlib
1 >>> import matplotlib
2 >>> dir(matplotlib)
(2) Dans quel rpertoire se trouve ce module ?
1 >>> matplotlib.path
2 ['/usr/lib/pymodules/python2.6/matplotlib']
(3) http://matplotlib.sourceforge.net/users/pyplot_tutorial.html#pyplot-tutorial
Solution 5.5.9 Elle dfinit une fonction echo (en lignes 1 et 2) lui donne un alias, x en ligne 3 et
lexcute (ligne 4).
Solution 48 Modifier une liste
(1) Modifie la liste
1 >>> def modif(L) :
2 ... L[0]='change'
(2) Ne modifie pas la liste
1 >>> def fidom(L) :
2 ... return ['change'] + L[1 :]
(3) test des deux fonctions :
5.5 Solutions des exercices 145
1 >>> l=[0,1]
2 >>> fidom(l)
3 ['change', 1]
4 >>> l
5 [0, 1]
6 >>> modif(l)
7 >>> l
8 ['change', 1]
Solution 49 Suite de Fibonacci
Solution 50 Richesse lexicale
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 def wordCount(text, n=3) :
5 return len(set(wordList(text,n)))
6
7 def lexicalRichness(text, n=3) :
8 words = wordList(text, n)
9 lsw = float(len(set(words)))
10 lw = len(words)
11 return lsw/lw
12
13 def frequence(words) :
14 frequence={}
15 for word in words :
16 try : frequence[word]+=1
17 except KeyError : frequence[word]=1
18 return frequence
19
20 def wordList(text, n=3) :
21 text = unicode(text,"utf-8")
22 text = text.replace(u'\'',u' ')
23 words = [w.strip("'.,;!?()' :").lower() for w in text.split()
if len(w)>n]
24 return(words)
25
26 if __name__=="__main__" :
27 text=open('petittexte.txt').read()
28 print wordCount(text)
146 Chapitre 5. Fonctions, scripts et modules
29 print wordCount(text, 4)
30 print lexicalRichness(text, 4)
31 mots = wordList(text, 4)
32 print sorted(mots)
33 print frequence(mots),
Solution 51 Passage darguments
modif() modifie son argument car cest une liste (modifiable).
fidom() ne modifie pas son argument car cest un entier (non modifiable).
Solution 52 Espace de nommage
Dans tout espace de nommage, une variable __name__ est en permanence accessible, et contient
le nom de lespace de nommage.
Dans une session Python , lespace de nommage est __main__.
Dans le module tests lespace de nommage est tests.
Lors de limportation du module tests, les instructions qui le composent sont excutes. Les-
pace de nommage est alors celui du module : __name__ vaut tests. Lexpression boolenne
__name__=="__main__" prend donc la valeur False les instructions du bloc ne sont pas excu-
tes.
Lors dune excution du script en ligne de commande Unix, lespace de nommage est __main__.
Lexpression boolenne __name__=="__main__" : prend donc la valeur True et les instructions
contenues dans le bloc sont excutes.
Solution 53 Rgles de porte
(1) >>> type(__builtins__) fournit la rponse : __builtins__ est de type dict ;
(2) >>> __builtins__.keys() donne la rponse ;
(3) __builtins__['max'] contient la fonction max() ;
(4) lespace de noms de la fonction max() est fournit par linstruction
>>> max.__module__ ;
(5) linstruction
>>> max=0.5
masque la fonction max() qui nest donc plus accessible ;
(6) si lon efface __builtins__['max'] par exemple avec
>>> __builtins__.pop('max')
... a plante ;
(7) Python refuse deffacer __builtins__ sans donner aucun message ;
(8) si lon masque __builtins__, avec linstruction
>>> __builtins__=12
la fonction max() par exemple, nest plus visible. Il suffit deffacer la variable builtins
qui masque la vraie __builtins__ par linstruction
5.5 Solutions des exercices 147
>>> del__builtins__
(9) SyntaxError : name 'x'is local and global (<input>, line 2)
Solution 54 Fonctions builtins
(1) Utilisation lmentaire
Max, min et moyenne dune liste N dentiers
>>> max(N), min(N), sum(N)/len(N)
Lecture de donnes
1 >>> for v in open('data.txt').readlines() :
2 ... exec(v.strip('#\n ').replace(' ','='))
(2) La fonction eval(expr) permet dvaluer lexpression expr tandis que la fonction exec(
inst) value linstruction inst. Par exemple :
1 >>> eval('1+1')
2 2
3 >>> exec('a = 1 + 1')
4 >>> print(a)
5 2
Solution 55 Somme des chiffres dun nombre entier
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 def som(N) :
4 """La somme des chiffres dans un nombre entier N, recursif"""
5 assert(type(N) is str)
6 if len(N)==1 :
7 return int(N)
8 else :
9 P=str(sum([int(i) for i in N]))
10 return som(P)
11
12 if __name__=="__main__" :
13 n='123'
14 print "som(%s)=%s"%(n,som(n))
Solution 56 Tours de Hano
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 """source : http ://fr.wikipedia.org/wiki/Tours_de_Hanoi"""
4 N=0
148 Chapitre 5. Fonctions, scripts et modules
5 def hanoi(n,de,vers,par) :
6 """
7 jeu de hanoi
8 il s'agit de deplacer des disques
9 de la tour A vers la tour B
10 """
11 global N
12
13 if n>0 :
14 N+=1
15 hanoi(n-1, de, par, vers)
16 print str(de),"-->",str(vers)
17 hanoi(n-1, par, vers, de)
18 return N
19
20 if __name__ == '__main__' :
21 print hanoi(5,'A','B','C'), ' dplacements'
Solution 57
Solution 58 Lecture dune trace GPS sur un fichier IGC.
1 #!/usr/bin/python
2 #-*-coding : utf-8 -*-
3
4 import os, numpy, scipy
5 from math import pi, cos, sin, acos, asin, sqrt
6 from lecture import *
7 def duree(P, Q, unit='mn') :
8 """Duree entre deux enregistrements"""
9 h,m,s=(f-d for d,f in zip(heure(P),heure(Q)))
10 if unit.lower() in ('m','mn') :
11 return 60*h+m+s/60.0
12 elif unit.lower() in ('h') :
13 return h+m/60.0
14 elif unit.lower() in ('sec','s') :
15 return (60*h+m)*60+s
16 else :
17 return None
18
19 def dureeTotale(records,unit='mn') :
20 """Renvoit la duree totale d'un vol"""
21 return duree(records[0],records[-1],unit)
5.5 Solutions des exercices 149
22
23 def vitesse(P,Q,unit='km/h') :
24 """Renvoit le couple (vitesse reelle, vitesse projetee) entre
les deux enregistrements P et Q"""
25 if unit.lower() in ('km/h') :
26 d = duree(P,Q,'h')
27 dr,dp = distance(P,Q,'km')
28 return (dr/d,dp/d)
29 elif unit.lower() in 'm/s' :
30 d = duree(P,Q,'s')
31 dr,dp = distance(P,Q,'m')
32 return (dr/d,dp/d)
33 else :
34 raise NotImplementedError,'Unite de vitesse non prise en
compte : %s'%unit
35
36 def vitesseMoyenne(records,unit='km/h') :
37 """Renvoit le couple (vitesse moyenne reelle, vitesse moyenne
projetee)"""
38 return vitesse(records[0],records[-1],unit)
39
40 def finesse(P,Q) :
41 """Renvoit le la finesse entre deux enregistrements, c'est a
dire le rapport distance horizontale/distance verticale"""
42 dp,dr=distance(P,Q,'m')
43 return dp/deniv(P,Q,'m')
44 def finesseMoyenne(records) :
45 return finesse(records[0],records[-1])
46
47 def deniv(P,Q,unit='m') :
48 """Retourne le denivele entre deux enregistrements. Unite=metre
49 todo :proposer d'autre unites'"""
50 return altitude(P)-altitude(Q)
51
52 def resume(trace) :
53 try : daterecord,modelerecord,pointsrecords = lecture(trace)
54 except IOError :
55 print 'fichier %s introuvable'%trace
56 exit()
57 print "Modele :",modele(modelerecord)
58 print "Date :",date(daterecord)
59 unite='h'
150 Chapitre 5. Fonctions, scripts et modules
60 print 'Duree : %.2f %s'%(dureeTotale(pointsrecords,unite),
unite)
61 unite='km/h'
62 vp,vr=vitesseMoyenne(pointsrecords,unite)
63 print 'Vitesse reelle : %.2f %s, projetee : %.2f %s'%(vr,
unite, vp,unite)
64 print 'Finesse : %.1f'%(finesseMoyenne(pointsrecords))
65 dp,dr = distance(pointsrecords[0],pointsrecords[-1])
66 unit='km'
67 print 'Distance reelle : %.2f %s, projetee : %.2f %s'%(dr,
unit,dp,unit)
68 unit='m'
69 print 'Denivelee : %.2f %s'%(deniv(pointsrecords[0],
pointsrecords[-1]),unit)
70
71 if __name__ == '__main__' :
72 resume('test.igc0')
On a rajout la fonction date(r) pour extraction de la date, ainsi que la fonction modele(r)
pour extraction du modle daronef
Solution 59 Rsum dun fichier IGC (suite).
Voir (5.5.9)
Solution 60 Fichier IGC, analyse dtaille (suite).
voir (5.5.9)
Solution 61 Todo
Solution 62 Dcorateurs
1 def unArgument(f) :
2 def _unArgument(*arg) :
3 #print '##', len(arg)
4 if len(arg) >1 :
5 print('Je ne prend que le premier argument : %s'%arg[0])
6 return f(arg[0])
7 return _unArgument
8
9 @unArgument
10 def g(x, y=0) : return x*x
11
12 if __name__ == "__main__" :
13 print(g(2))
5.5 Solutions des exercices 151
14 print(g(1,3))
Solution 63 Dcorateur
1 def Majuscule(f) :
2 def _Majuscule(arg) :
3 return f(arg.upper())
4 return _Majuscule
5
6 @Majuscule
7 def g(x) : print(x)
Solution 64 Profilage
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import random
4 import profile as prof
5 from math import sin
6 N=1000
7 biglist = [random.randint(-100,100) for i in range(N
)]
1
2 def map_without_list_comprehension() :
3 for i in range(100) :
1
2 def map_with_list_comprehension() :
3 for i in range(100) :
1
2 print ("===== map_without_list_comprehension =====")
3 prof.run('map_without_list_comprehension()')
4 print ("===== map_with_list_comprehension =====")
On obtient les rsultats suivants :
152 Chapitre 5. Fonctions, scripts et modules
===== map_without_list_comprehension =====
200105 function calls in 1.040 CPU seconds
...
===== map_with_list_comprehension =====
200005 function calls in 1.176 CPU seconds
...
En effectuant plusieurs fois le test, on calcule la moyenne des temps dexcution :
map List comprehension
1.024 1.080
1.208 1.116
1.072 1.164
1.040 1.176
1.104 1.136
1.124 1.212
moyenne 1.095 1.147
Tab. 2. Comparaison des temps dexcution map()/list comprehension
Lutilisation des list comprehension produit un code environ 5% plus lent que la fonction map().
CHAPITRE 6
Programmation oriente objet
Les principales caractristiques des classes Python sont :
lhritage permet la multiplicit des classes de base ;
une classe drive peut surcharger nimporte quelle mthode de sa ou ses classes de base ;
une mthode peut appeler une mthode de sa classe de base avec le mme nom;
les objets peuvent contenir un nombre arbitraire dattributs prives ;
tous les membres dune classe (dont les donnes membres) sont publics ;
toutes les mthodes sont virtuelles. Il ny a pas de constructeurs ou de destructeurs particu-
liers ;
toute mthode est dclare avec un premier argument explicite (self le plus souvent) qui
reprsente lobjet, qui est fourni implicitement lappel ;
les classes sont elles-mmes des objets, mais dans un sens plus large : en Python, tous les
types de donnes sont des objets ;
les types intgrs peuvent tre utiliss comme classes de base pour des extensions par lutili-
sateur ;
la plupart des oprateurs intgrs qui ont une syntaxe particulire (oprateurs arithmtiques,
indiage, etc.) peuvent tre surchargs.
6.1. Une premire approche des classes
Si les types de donnes de base de Python (listes, entiers, rels, dictionnaires...) ne sont pas
adapts vos besoins, crez une nouvelle classe.
Une classe cre par un programmeur est un nouveau type. Supposant que les complexes nexistent
pas en Python natif, si un mathmaticien a besoin du type complexe, il crera une classe Complexe
dont le comportement sera sa convenance.
lutilisation, il se pourrait que la dclaration >>> z=Complexe(1, 2.3) convienne notre
mathmaticien, qui voudra peut-tre galement crire >>> w = Complexe(1.0, 3.1) puis Z =
w * z.
La cration de la classe complexe devra rpondre ce cahier des charges (simplifi).
Comme toute entit Python, une classe est un object du langage Python que nous examinons
un peu plus loin (voir paragraphe 6.1.3 page 155).
Lobjet class Complexe (de type class) et lobjet z (de type Complexe) sont deux choses dif-
frentes. Lobjet z est une instance de la classe Complexe.
154 Chapitre 6. Programmation oriente objet
6.1.1. Syntaxe. La forme la plus simple de dfinition de classe ressemble ceci :
1 class NomClasse :
2 instructions
Les dfinitions de classe, comme les dfinitions de fonction doivent tre excutes pour entrer
en effet.
1
Dans la pratique, les instructions seront souvent des dfinitions de mthodes, mais dautres ins-
tructions sont acceptes.
A lentre dune dfinition de classe, un nouvel espace de noms est cr et utilis comme porte
locale.
Lorsque la dfinition de la classe est acheve de faon normale, un objet de type class est cr.
6.1.2. Une classe Complexe. Voici le code dune classe Complexe sommaire et incomplte :
1 class Complexe(object) :
2 """Une classe complexe sommaire"""
3 def __init__(self, re=0.0, im=0.0) :
4 self._x,self._y = re,im
5
6 def mod(self) :
7 return sqrt(self._y*self._y+self._y*self._y)
class est un mot cl, Complexe le nom de la classe. Cette ligne alerte linterprteur : je
veux crer un objet Python de type class, une nouvelle classe (et non pas un objet de type
Complexe qui, lui, sera cr plus loin). La classe Complexe hrite de la classe object, cest
dire que tous les attributs de la classe object peuvent tre utiliss par notre nouvelle classe.
(voir la section 6.2 page 157)
il est recommander dcrire une docstring destine expliquer le fonctionnement, avant toute
autre instruction.
la premire mthode est un constructeur (mthode spciale) : __init__ ses trois arguments
sont
(1) self : dsigne lobjet non encore instanci, de type Complexe, qui appelera cette m-
thode. Autrement dit, self est un Complexe, qui nexiste pas encore.
2
(2) re et im sont les parties relle et imaginaire, (par dfaut 0.0 et 0.0)
Il y a cration de deux attributs _x et _y, dans self. Ces attributs prendront corps en
mme temps que self, lorsque un Complexe sera instanci.
1
Il est possible de placer une dfinition de classe dans une branche dune instruction if, ou lintrieur dune
fonction.
2
De manire analogue, au moment de la dfinition dune fonction (par exemple def f(x) : return x*x) x ne
dsigne aucune variable, mais prendra corps seulement lorsque la fonction sera appele par exemple a=3;f(a).
6.1 Une premire approche des classes 155
mod() est une mthode qui calcule le module du complexe self. Largument self prendra
la valeur z lorsque sera excute linstruction z.mod().
Les classes introduisent trois nouveaux types dobjets : les objets classe, les objets instances et
les objets mthodes, que nous examinons maintenant.
6.1.3. Objets Classes. En Python , une classe est de type type, tout comme les types de
base int, str, etc..
3
Les objets classe admettent deux sortes doprations :
Les rfrences aux attributs : utilisent la syntaxe standard utilise pour toutes les rfrences
dattribut en Python : objet.nom. Par exemple pour la classe Complexe dfinie plus loin,
les rferences suivantes sont valides :
Complexe.mod,Complexe.__init__ renvoient des objets de type function
Complexe._x, Complexe._y renvoient des objets de type float
Complexe.__doc__ renvoit la docstring, de type str
Attention, il est possible daffecter une valeur aux attributs de classe, par simple affecta-
tion. Par exemple linstruction suivante est valide
1 >>> def f() : print 'hello'
2 >>> Complexe.mod = f
Linstantiation de classe, consiste crer un objet de la classe. Utilise la notation dappel de
fonction. Faites comme si lobjet classe tait une fonction qui renvoie une instance nouvelle
de la classe. Par exemple linstruction
1 >>> z = Complexe(1,2)
cre une nouvelle instance de la classe et affecte cet objet la variable locale z. Cette
instruction dclenche un appel Complexe.__init__(1,2), Les attributs z._x, z._y de-
viennent effectif, lintrieur de z. On dit que z est instanci.
6.1.4. Objets Instances.
Les seules oprations acceptes par des objets instance sont des rfrences leurs attributs. Il y
a deux sortes de noms dattributs valides.
les donnes (data attributes) : _x et _y dans la classe Complexe
les mthodes (methods) : une mthode est une fonction lie une instance. Par exemple z.
__init__(), z.mod() dans la classe Complexe
3
En Python 2, les objets classes sont de type classobj, contrairement aux types de base qui sont de type type. En
ce sens, une classe nest pas un quivalent strict dun type de base.
156 Chapitre 6. Programmation oriente objet
6.1.5. Objets Mthodes. Python fait une distinction entre la mthode z.mod() associe
une instance, et la fonction Complexe.mod() associe la classe
4
. Ce ne sont pas les mme
objets :
1 >>> class A :
2 ... def f(self) :pass
3 ...
4 >>> A.f
5 <function f at 0xb7107b2c>
6 >>> a=A()
7 >>> a.f
8 <bound method A.f of <__main__.A object at 0xb71141ac>>
On adoptera la mme terminologie que Python en parlant de fonction (ou fonction-mthode) pour
une classe et de mthode pour une instance.
Usuellement, une mthode est appele de faon directe, par exemple : >>> z.mod(). Dans lexemple
de la classe Complexe, cette instruction renverrait le module du complexe z. Dans cette instruc-
tion, la mthode a t appele sans argument, alors que sa dfinition en spcifiait un. Python
aurait d lever une exception ?
Non, et cest la particularit des mthodes : lobjet est pass comme premier argument la fonc-
tion.
z.mod()
est strictement quivalent
Complexe.mod(z)
La diffrence entre une mthode et une fonction tient ce que la mthode est appele sans son
premier argument, qui est implicitement linstance de lappelant.
Autrement dit : dans la mthode Complexe.mod(self), largument self vaut z. Ainsi il est
parfaitement lgitime, bien que moins lgant, dappeler Complexe.mod(z) au lieu de z.mod().
6.1.6. Quelques remarques.
Le premier argument dune mthode est, par convention, appel self, a nest quune conven-
tion quil est fortement conseill de suivre, dfaut de quoi le programme peut devenir rapi-
dement illisible.
Contrairement au C++ o le this est facultatif, en Python, il ny a pas de raccourci pour
faire rfrence aux attributs dune classe partir dune mthode. Ainsi lexemple suivant est
valide :
4
En Python 2, Complexe.mod() tait une mthode, mais une mthode non lie (unbound method)
6.2 Hritage simple, multiple 157
1 class Complexe :
2 def mod(self) :
3 return sqrt(self._x*self._x+self._y*self._y)
Tandis que lexemple suivant lvera lexception NameError indiquant que _x nest pas
dfini :
1 class Complexe :
2 def mod(self) :
3 return sqrt(_x*_x+_y*_y)
La dfinition des mthodes nest pas ncessairement comprise dans la dfinition de la classe.
Lexemple suivant est valide :
1 def ext(self,x) : return 2*x
2 class C :
3 f=ext
4 #etc...
6.2. Hritage simple, multiple
Linstruction :
1 class Complexe(object) :
signifie que la classe Complexe hrite de la classe object (qui est une classe Python de base).
Donc Complexe est un object de Python.
Grce cet hritage, tous les attributs et les mthodes de la classe object peuvent tre utiliss
et/ou surchargs par les instances de la classe Complexe.
Une classe Python doit toujours hriter dune autre classe. minima, si lon cre une classe ex-
abrupto, on la fera hriter de la classe de base object. Mme si on omet cet hritage, Python le
fera de lui mme. Par exemple :
1 >>> class A :pass
2 ...
3 >>> type(A)
4 <class 'type'>
5 >>> issubclass(A,object)
6 True
Une classe utilisateur peut hriter indiffrement dune classe de base Python ou bien dune autre
classe utilisateur.
158 Chapitre 6. Programmation oriente objet
6.2.1. Hritage ou pas ? Cest un question dune importance fondamentale pour le dvelop-
pement de classes rutilisables. Une mauvaise rponse cette question dbouche immanquable-
ment sur des problmes inextricables. Des programmeurs chevronns se sont laisss prendre au
pige.
On utilise un hritage lorsque lhritier est un parent, comme dans une filiation de famille ordi-
naire. Le fils Dupond est un Dupond.
La seule bonne question se poser pour dcider si B doit hriter de A est :
B is A ou bien B has A?
Si la rponse est B is A, alors B doit hriter de A,
Si la rponse est B has A, alors B doit avoir un attribut A.
Par exemple :
un cercle nest pas un Complexe, ni mme un centre. Un cercle possde un centre (donc
un Complexe), une classe Cercle nhritera pas de Complexe, mais possdera un attribut
Complexe, quon appellera probablement _centre.
Par contre un carr est un polygne. Un triangle galement. Donc les classes Carre et Triangle
hriteront de la classe Polygone.
Nous dveloppons cet exemple dans les paragraphes suivants.
6.2.2. Exemple de la classe Polygone TODO : commenter. En supposant que lon dispose
dune classe Polygone, comme celle-ci :
1 class Polygone(object) :
2 def __init__(self, liste_de_points) :
3 self.points = liste_de_points
4
5 def isClosed(self) :
6 return self.points[0] == self.points[-1]
7
8 def close(self) :
9 if not self.isClosed() :
10 self.points.append(self.points[0])
11
12 def longueur(self) :
13 return sum([abs(z1-z0) for (z0,z1) in
14 zip(self.points[ :-1],self.points[1 :])])
on pourra dfinir une classe Triangle hritant de la classe Polygone comme ceci :
6.2 Hritage simple, multiple 159
1 from polygone import Polygone
2
3 class Triangle(Polygone) :
4
5 def __init__(self, liste) :
et lutiliser ainsi :
1 self.close()
2
3 def __str__(self) :
4 return'Triangle : '+Polygone.__str__(self)
etc...
6.2.3. Surcharge. Dans la terminologie C++, toutes les mthodes en Python sont virtuelles,
ce qui signifie dune part que lon peut les surcharger. Dautre part, lorsquune mthode est sur-
charge, linterprteur Python dcide dynamiquement - lexcution donc- laquelle des deux m-
thodes il doit utiliser (la mthode surcharge ou bien la mthode parent), suivant le type de lap-
pelant :
1 >>> class A :
2 ... def f(self) : return 'Ah, bonjour'
3 >>> class B(A) : pass
4 >>> class C(A) :
5 ... def f(self) : return "C'est bien"
6 >>> a, b, c = A(), B(), C()
7 >>> a.f()
8 'Ah, bonjour'
9 >>> b.f()
10 'Ah, bonjour'
11 >>> c.f()
12 "C'est bien"
Dans cet exemple,
linvocation de la mthode a.f() dclenche un appel la fonction A.f() de la classe A,
linstruction b.f() appelle galement la fonction A.f() de la classe A. Puisque la classe B
na pas de fonction f(), linterprteur parcourt les anctres de B pour trouver une fonction
nomme f(), quil trouve dans la classe A.
linvocation de b.f(), la fonction B.f() est appele. Cette fonction masque la fonction
A.f(). On dit que la fonction B.f() surcharge la fonction A.f().
160 Chapitre 6. Programmation oriente objet
De mme, dans lexemple 6.2.2 page 158, la mthode spciale Triangle.__str__() surcharge
celle de Polygone.__str__().
Une question rcurrente survient lorsque la mthode de lhritier doit seulement complter la
mthode du parent plutt que la redfinir en totalit. Dans ce cas, on voudrait appeler la mthode
parent, puis effectuer le traitement spcifique la mthode enfant. la lumire de ce quon a
vu au paragraphe 6.1.5 page 156, il suffit dappeler la mthode du parent comme une fonction
ordinaire. Voici un exemple :
1 >>> class A :
2 ... def f(self) : return 'Hello'
3 >>> class B(A) :
4 ... def f(self) :
5 ... return A.f(self)+', world !'
6 >>> b = B()
7 >>> b.f()
8 >>> 'Hello, world !'
La mthode b.f() appelle tout dabord explicitement la fonction A.f(), puis effectue son propre
traitement. Linstance b ne peut accder la A.f() quen la qualifiant compltement. Le mas-
quage de la fonction A.f() par la mthode b.f() nest pas total, elle reste accessible comme
fonction de la classe A.
6.2.4. Hritage multiple. Python supporte aussi une forme limite dhritage multiple. Une
dfinition de classe avec plusieurs classes de base scrit ainsi :
1 class NomClasseDerivee(Base1, Base2, Base3) :
2 instructions ...
La seule rgle permettant dexpliquer la smantique de lhritage multiple est la rgle de rso-
lution utilise pour les rfrences aux attributs. La rsolution se fait en profondeur dabord, de
gauche droite. Donc, si un attribut nest pas trouv dans NomClasseDerivee , il est cherch
dansBase1, puis (rcursivement) dans les classes de base de Base1, et seulement sil ny est pas
trouv, il est recherch dans Base2, et ainsi de suite.
Lutilisation banalise de lhritage multiple est un cauchemar de maintenance.
6.3. La classe object
1 >>> A.mro()
2 [<class '__main__.A'>, <class 'object'>]
3 >>> class A(object) :pass
4 ...
5 >>> A.mro()
6.4 Mthodes spciales 161
6 [<class '__main__.A'>, <class 'object'>]
Dans cet exemple, on utilise la methode mro() (initiales de Mthode Resolution Order), hrite
du type object. Cette mthode indique lordre de parcours des classe parentes lors de la recherche
dun attribut dune classe donne.
6.4. Mthodes spciales
Les mthodes spciales commencent et finissent par __ (deux underscores _). Elles sont hrites
de la classe object.
La liste de ces mthodes spciales se trouve dans la documentation Python de la classe object :
http://docs.python.org/reference/datamodel.html
Par exemple, si lon veut pouvoir crire z = z1+z2 pour z1 et z2 de type Complexe, il suffit de
surcharger la mthode Complexe.__add__(self, z) dans la classe Complexe en sachant que
z = z1 + z2
est strictement quivalent
z = z1.__add__(z2)
On crira donc dans la classe Complexe :
1 def __add__(self, z) :
2 self._x += z._x
3 self._y += z._y
Le tableau suivant numre quelques mthodes spciales que lon peut surcharger dans une classe
C donne ( condition que celle-ci hrite de la classe object). La liste complte se trouve sur
http://docs.python.org/reference/datamodel.html#specialnames.
x et y sont deux instances de classe C
162 Chapitre 6. Programmation oriente objet
Mthode surcharger Exemple dutilisation quivalence
C.__add__(self, y) x + y x.__add__(y)
C.__sub__(self, y) x - y x.__sub__(y)
C.__mul__(self, y) x * y x.__mul__(y)
C.__and__(self, y) x and y x.__and__(y)
C.__or__(self, C) x or y x.__or__(y)
C.__len__(self) len(x) x.__len__()
C.__getitem__(self,i) x[i] x.__getitem__(i)
C.__setitem__(self,i,val) x[i]=3 x.__setitem__(i,3)
C.__call__(self[,args...]) x(args) x.__call__(args)
C.__str__(self) str(z) x.__str__()
C.__repr__(self) repr(x) x.__repr__()
Quelques remarques :
__repr__() devrait retourner une reprsentation de son argument qui soit lisible par linter-
prteur. Autrement dit, eval(repr(z)) devrait retourner une copie de z.
Linstruction str(z) est en ralit un appel z.__str__()
__str__() devrait retourner une reprsentation de son argument qui soit confortablement
lisible pour luil humain.
La commande print ne sait afficher que des chanes de caractres. Linstruction print z
convertit tout dabord z en string par un appel z.__str__(), puis affiche la chane de
caractres.
6.5. Variables prives
Il y a un support limit pour des identificateurs privs dans une classe. Tout identificateur de la
forme __spam (au moins deux tirets-bas au dbut, au plus un tiret-bas la fin) est maintenant
textuellement remplac par _nomclasse__spam , o nomclasse est le nom de classe courant,
duquel les tirets-bas de dbut on t enlevs.
Pour limiter ou interdire laccs un attribut dune classe, on utilisera avec profit la notion de
property, prsente au paragraphe 6.6.
Les dcorateurs ( 5.4 page 129) fournissent un moyen efficace.
6.6. Les properties
Une property est un attribut de classe, gre par un getter et un setter
5
.
Une property est dclare par la fonction property()
5
Un setter permet daffecter (set) une valeur un attribut, un getter permet de rcuprer (get) la valeur de cet attribut.
La traduction franaise, accesseur en lecture et accesseur en criture , en tant peu commode nous adoptons
les mots anglais getter et setter.
6.6 Les properties 163
Cest un moyen lgant pour autoriser lutilisateur dune classe accder -en lecture comme en
criture- un attribut de la classe, avec une syntaxe allge, tout en conservant le contrle sur cet
accs.
Supposons que lon ait besoin de garder le contrle sur le type dune affectation : on veut tre
assur que lattribut altitude de la classe Montagne soit de type float. La solution usuelle (en
C++ par exemple) est dcrire une mthode de type setter, nomm Montagne.setAltitude()
qui sacquitera de cette vrification et renvoit un message en cas derreur. Supposant que colline
est une instance de Montagne, on peut alors crire :
1 >>> colline.setAltitude("hyper haut")
La syntaxe est lourde. On aimerait pouvoir crire de manire plus naturelle :
1 >>> colline.altitude = "hyper haut"
tout en tant certain que la rponse soit identique, par exemple
1 Attention, altitude doit tre un nombre rel.
La fonction property() autorise ce comportement.
Cet exemple basique illustre le fonctionnement de la fonction property() :
1 class Montagne(object) :
2 def _getAltitude(self) :
3 return self._alt
4 def _setAltitude(self, alt) :
5 if type(alt) in (float,int) :
6 self._alt = float(alt)
7 else :
8 raise TypeError('"%s" doit etre numerique'%alt)
9 altitude = property(_getAltitude, _setAltitude)
Une instance >>> s=Montagne() est cre, puis lutilisateur prcise laltitude avec une syntaxe
simplifie :
1 >>> s.altitude = 4807!
164 Chapitre 6. Programmation oriente objet
Linterprteur Python identifie altitude comme une property qui doit prendre la valeur 4807.
Il appelle alors le setter de altitude, cest dire _setAltitude().
Pour lutilisateur, la notion de property est transparente. Elle permet de dfinir, comme en C++des
getters et des setters, avec une vrification de type si ncessaire, mais avec une syntaxe lgre
pour lutilisateur.
Au niveau de la programmation, cela demande au programmeur un effort initial.
La signature de property est :
property(fget=None, fset=None, fdel=None, doc=None)
fget est la mthode getter de lattribut
fset le setter
fdel est le destructeur de lattribut
doc est une chane de caractres contenant la documentation de lattribut
Une dclaration plus complte de la property Montagne.altitude pourrait tre
1 altitude = property(fget=_getAltitude,fset=_setAltitude,doc="l'
altitude en mtres")
La documentation de Montagne.altitude est comme de coutume dans sa docstring Montagne
.altitude.__doc__, accessible par
1 >>> help(Montagne.altitude)
6.7. Manipulation dynamique des attributs
Python est un langage reflectif, qui supporte la mtaprogrammation. Il est possible dcrire un
programme Python qui gnre puis excute un programme Python . Une illustration de cette
technique est donne par le package PyPy qui Les fonctions builtins setattr(), getattr(),
hasattr() sont conues pour crer, acqurir et consulter des attributs dans une classe. Voici un
exemple simple dutilisation :
1 >>> class A(object) :
2 ... pass
3 ...
4 >>> a = A()
5 >>> setattr(a, 'un_attribut',3.14)
6 >>> hasattr(a,'un_attribut')
7 True
8 >>> a.un_attribut
9 3.1400000000000001
10 >>> delattr(a,'un_attribut')
6.8 Slots 165
11 >>> hasattr(a,'un_attribut')
12 False
setattr(objet, nom, valeur) permet dajouter lattribut nom objet, avec la valeur
valeur
delattr(objet, nom) pour supprimer lattribut nom objet
hasattr(objet, nom) renvoit True ou False suivant que objet possde ou non un attribut
nom.
6.8. Slots
__slots__ par dfaut, chaque instance dune classe possde son propre dictionnaire pour y sto-
cker ses attributs. Lorsque le nombre dinstances est importat, cette particularit est trs consom-
matrice en mmoire vive. Ce comportement des classes Python peut tre modifi par la dcla-
ration de __slots__. Dans ce cas, lorsquune squence dinstances de la classe est cre, seul
lespace mmoire ncessaire aux attributs dclars est utilis, et le dictionnaire nest pas cr.
__slots__ est une variable de classe laquelle est affecte une chane, un itrable ou une s-
quence de chanes, contenant les noms des attributs dclars.
Exemple :
1 >>> class A(object) :
2 ... __slots__="x"
3 >>> a = A()
4 >>> class B(object) :
5 ... pass
6 >>> b = B()
7 >>> import sys
8 >>> sys.getsizeof(a)
9 56
10 >>> sys.getsizeof(b)
11 64
Les objets de classe A sont effectivement plus petits que les objets de type B :
1 >>> import sys
2 >>> sys.getsizeof(a)
3 56
4 >>> sys.getsizeof(b)
5 64
Comme il ny a pas de dictionnaire attach une instance de la classe, il est impossible de lui
rajouter un attribut :
166 Chapitre 6. Programmation oriente objet
1 >>> a.__dict__
2 Traceback (most recent call last) :[...]
3 AttributeError : 'A' object has no attribute '__dict__'
4 >>> b.__dict__
5 {}
6 >>> a.y = 7 # ou setattr(a,'y',7)
7 Traceback (most recent call last) :[...]
8 AttributeError : 'A' object has no attribute 'y'
9 >>> b.y = 7
10 >>> import sys
Lattribut de classe __slots__ doit dclarer tous les attributs de la classe.
1 >>> class C(object) :
2 __slots__ = "x"
3 def __init__(self) :
4 self.x = 0
5 self.y = 1
6 >>> c = C()
7 Traceback (most recent call last) :[...]
8 self.y = 1
9 AttributeError : 'C' object has no attribute 'y'
Exercices
Exercice 65. Richesse lexicale dun texte
partir des rsultats de lexercice 5.5.9 page 138, crer une classe Texte capable de lire un
fichier ASCII, compter le nombre de mots qui le compose, crer un dictionnaire des mots, avec
leur frquence, calculer la richesse lexicale du texte.
Voici un cahier des charges :
1 >>> RL = Texte('petittexte.txt')
2 >>> RL.wordCount()
3 22
4 >>> RL.wordsDict() #dictionnaire frquences
5 {u'etage' : 2, u'dessus' : 1, ... u'actuellement' : 1}
6 >>> RL.lexicalRichness()
7 0.759...
6.8 Exercices 167
Exercice 66. Polygnes
Crer une classe Polygone reprsentant les polygnes du plan, utilisant le type complex de
Python , et dont le comportement rpondra au cahier des charges minimum suivant :
1 >>> p = Polygone([0,1, 1+1j, 1j])
2 >>> print (p.point(1),p.point(2))
3 (1, (1+1j))
4 >>> print (p.isClosed())
5 False
6 >>> print (p.longueur())
7 3.0
8 >>> p.close()
9 >>> print (p.isClosed())
10 True
11 >>> print (p.longueur())
12 4.0
13 >>> print (p)
14 <__main__.Polygone object at ...>
Exercice 67. Classe, rutilisabilit
(1) Dans la classe Complexe, crire une mthode arg() qui retourne largument du complexe.
Testez.
(2) Ecrire une version fonction de la mthode prcdente qui se comportera de manire naturelle
>>> print arg(z).
(3) Crer une mthode de Complexe.dist(...) qui utilise ainsi >>> z.dist(z1), renvoit la
distance entre les Complexes z et z1 considrs comme des points du plan.
(4) Crer une version fonction de la mthode prcdente qui sutilise ainsi : >>> dist(z0,z1)
(5) Dans la classe Complexe, crire une mthode __repr__() qui renvoit le complexe sous forme
dune chane de caractres agrable lire.
(6) Testez cette mthode par linstruction >>> print(z.__repr__()), comparer avec >>>
print(z).
Exercice 68. Hritage Triangle
crire une classe Triangle qui hrite la classe Polygone dfinie lexercice 66 et tester ses
diffrents composants. Ecrire en particulier une mthode aire() qui calcule laire du triangle.
Exercice 69. Hritage dun type de base
Revisiter la classe Polygone de lexercice 66.
Faites la hriter du type list
Profitez de cet hritage pour simplifier limplmentation de la classe Polygone.
Vrifiez que cette nouvelle classe rpond au cahier des charges de lexercice 66
168 Chapitre 6. Programmation oriente objet
Ajouter ensuite les fonctionnalits rpondant au cahier des charges :
1 >>> p=Polygone([0,1,1+1j])
2 >>> p.append(1j)
3 >>> p.close()
4 >>> p
5 [0j, (1+0j), (1+1j), 1j, 0j]
6 >>> p.aire()
7 1.0
Soit un polygne (ferm), de sommets complexes (z
j
)
0jn
avec z
0
= z
n
. Alors laire du polygne
est donn par
6
A =
1
2
1jn
(z
j
.z
j+1
)
o (z) et z dsignent la partie imaginaire et le conjugu du complexe z.
crire et tester une mthode Polygone.aire()
Exercice 70. Hritage.
Ecrire une classe Tableau qui hrite de la classe list,
dont la fonction __init__(self, l) permet de vrifier que largument l est une liste dont
tous les lments sont dun type numrique : int, long, float ou complex
qui permet dcrire les instructions :
1 >>> a=Tableau([1,2,3])
2 >>> a.norm()
3 >>> a.norm(1)
4 >>> len(a)
5 >>> b=Tableau([2,3,4])
6 >>> a+b
7 >>> a*b #produit scalaire
8 >>> a(3) = 12
9 >>> a[3] = 12
Exercice 71. Mthodes spciales
Dans la classe Complexe,
(1) implmenter une mthode __add__() et une mthode __mul__(). Testez ensuite linstruction
>>> print z0+z1, z1*z0 ;
(2) implmentez correctement la mthode __repr__ dans la classe Complexe, puis testez les
instructions
6
voir http://fr.wikipedia.org/wiki/Aire_et_centre_de_masse_d'un_polygone
6.8 Exercices 169
1 >>> z = Complexe(1,2)
2 >>> z == eval(repr(z))
Exercice 72. Mthodes spciales
En ligne de commande Python , dclarez une classe A : >>> class A : pass. Puis crez une
instance a de la classe A
Crer une fonction p qui se contente dimprimer "hello" et utiliser la fonction setattr() pour
attacher p comme mthode de la classe A sous le nom de __str__() (fonction ).
Testez linstruction >>> print a et interprtez le rsultat
Exercice 73. Property
Dans la classe Complexe, crer une property x, pour accder la partie relle (lecture et criture)
avec la syntaxe suivante :
1 >>> z = Complexe(1,2)
2 >>> z.x
3 2
4 >>> z.x = 3.14
Modifier le setter de la property x pour quil effectue une vrification sur le type et lve une
exception lorsque lon tente daffecter la partie relle un type non attendu, comme ceci :
1 >>> z0 = Complexe(1,2)
2 >>> z0.x = "12.0"
3 Traceback (most recent call last) :
4 File "./prop.py", line 40, in <module>
5 z0.x = "12"
6 File "./prop.py", line 29, in _setx
7 raise TypeError,"Complexe.x : %s non supporte"%(type(value))
8 TypeError : Complexe.x : <type 'str'> non supporte
Exercice 74. slots
Soient A et B les classes dfinies ainsi :
1 class A(object) :
2 __slots__="x"
3 def __init__(self) :
4 x = 0
5
6 class B(object) :
7 def __init__(self) :
170 Chapitre 6. Programmation oriente objet
8 x = 0
crire un script comprenant deux courtes fonctions qui testent la cration de N objets de classe
A, puis de classe B, utiliser la fonction cProfile.run() pour tester les temps dexcution.
Solutions des exercices
Solution 65 Richesse lexicale dun texte
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 class Texte(object) :
4
5 def __init__(self, nom_fichier, word_size=4) :
6 self.size = word_size
7 try :
8 self.text = open(nom_fichier).read()
9 except IOError :
10 print ("Impossible de lire le fichier %s"%nom_fichier)
11 self.setWordList()
12
13 def setWordList(self) :
14 #self.text = unicode(self.text,"utf-8")
15 self.text = self.text.replace('\'',' ')
16 self.words = [w.strip("'.,;!?()' :").lower()
17 for w in self.text.split() if len(w)>self.size]
18
19 def wordCount(self) :
20 return len(set(self.words))
21
22 def lexicalRichness(self) :
23 return float(len(set(self.words)))/len(self.words)
24
25 def wordsDict(self) :
26 self.frequence={}
27 for word in self.words :
28 try : self.frequence[word]+=1
29 except KeyError : self.frequence[word]=1
30 return self.frequence
31
32 if __name__=="__main__" :
33 RL = Texte('petittexte.txt')
34 print(RL.wordCount())
6.8 Solutions des exercices 171
35 print(RL.wordsDict())
36 print(RL.lexicalRichness())
Solution 66 Polygnes
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 class Polygone(object) :
5 def __init__(self, liste_de_points) :
6 self.points = liste_de_points
7
8 def isClosed(self) :
9 return self.points[0] == self.points[-1]
10
11 def close(self) :
12 if not self.isClosed() :
13 self.points.append(self.points[0])
14
15 def longueur(self) :
16 return sum([abs(z1-z0) for (z0,z1) in
17 zip(self.points[ :-1],self.points[1 :])])
18 def point(self,i) : return self.points[i]
19
20 if __name__ == "__main__" :
21 p = Polygone([0,1, 1+1j, 1j])
22 print (p.point(1),p.point(2))
23 print (p.isClosed())
24 print (p.longueur())
25 p.close()
26 print (p.isClosed())
27 print (p.longueur())
28 print (p)
Solution 67 Classe, rutilisabilit
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 from math import sqrt, atan2
5
6 class Complexe() :
7 """Une classe complexe sommaire"""
172 Chapitre 6. Programmation oriente objet
8 def __init__(self, re=0.0, im=0.0) :
9 self._x,self._y = re,im
10
11 def abs(self) :
12 return sqrt(self._x*self._x+self._y*self._y)
13
14 def arg(self) :
15 return atan2(self._x,self._y)
16
17 def __repr__(self) :
18 return "%f+%fI"%(self._x,self._y)
19
20 def dist(self,z) :
21 return Complexe(self._x-z._x,self._y-z._y).abs()
22
23 def arg(z) :
24 return z.arg()
25
26 def dist(z1,z2) :
27 return z1.dist(z2)
28
29 if __name__ == "__main__" :
30 z0 = Complexe(1,2)
31 z1 = Complexe()
32 print (z0.arg(),"==", arg(z0))
33 print (dist(z0,z1),"==",z0.dist(z1))
34 print (z0,"==", z0.__repr__())
Solution 68 Hritage Triangle
TODO
Solution 69 Hritage dun type de base
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 class Polygone(list) :
5 def __init__(self, liste_de_points) :
6 list.__init__(self,[complex(z) for z in liste_de_points])
7
8 def isClosed(self) :
9 return self[0] == self[-1]
10
6.8 Solutions des exercices 173
11 def close(self) :
12 if not self.isClosed() :
13 self.append(self[0])
14
15 def longueur(self) :
16 return sum([abs(z1-z0) for (z0,z1) in zip(self[ :-1],self[1
:])])
17 def aire(self) :
18 return 0.5*sum([(z0.conjugate()*z1).imag
19 for (z0,z1) in zip(self[ :-1],self[1 :])])
20
21 if __name__ == "__main__" :
22 p=Polygone([0,1,1+1j])
23 p.append(1j)
24 p.close()
25 print (p, p.aire())
Solution 70 Todo
Solution 71 Mthodes spciales
Voici une classe Complexe un peu plus complte :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3
4 from math import sqrt, atan2
5 class Complexe(object) :
6 """Une classe complexe sommaire"""
7 def _getx ( self ) : return self._x
8 def _setx(self, a) :
9 try : self._x = float(a)
10 except ValueError : print ("float(%s) : impossible"%a)
11 x = property(_getx, _setx,doc="partie relle")
12 def _gety ( self ) : return self._x
13 def _sety(self, a) :
14 try : self._y = float(a)
15 except ValueError : print ("float(%s) : impossible"%a)
16 y = property(_gety, _sety,doc="partie imaginaire")
17
18 def __init__(self, re=0.0, im=0.0) :
19 self.x, self.y = re, im
20
21 def __abs__(self) :
174 Chapitre 6. Programmation oriente objet
22 return sqrt(self.x*self.x+self.y*self.y)
23
24 def arg(self) : return atan2(self.x,self.y)
25
26 def __str__(self) : return '(%s + %si)'%(self.x,self.y)
27
28 def __repr__(self) : return "Complexe(%f,%f)"%(self.x,self.y)
29
30 def __add__(toto,z) :#toto+z
31 return Complexe(toto.x+z.x,toto.y+z.y)
32
33 def __mul__(self, z) :
34 return Complexe (self.x*z.x-self.y*z.y,self.x*z.y+self.y*z.x
)
35
36 def conj(self) : return Complexe(self.x, -self.y)
37
38 def inv(self) :
39 a = self.x*self.x+self.y*self.y
40 return Complexe(self.x/a,-self.y/a)
41
42 def __getitem__(self,i) :
43 if i == 1 : return self.x
44 if i == 2 : return self.y
45 raise IndexError( "Complexe[%d] inaccessible"%i)
46
47 def __setitem__(self,i,val) :
48 if i == 1 :
49 self.x = val
50 return
51 elif i == 2 :
52 self.y = val
53 return
54 raise IndexError( "Complexe[%d] inaccessible"%i)
55 def inv(z) : return z.inv()
56 def conj(z) : return z.conj()
57
58 if __name__ == "__main__" :
59 z0=Complexe(1,2)
60 #z1=Complexe(2,3)
61 print (z0.x,z0._y)
62 z0.x = "0.5"
6.8 Solutions des exercices 175
63 print (z0.x)
64 z0.x = "aaa"
65 print (z0.x)
66 print ("z0._x est toujours accessible : ",z0._x)
67 print (z0)
68 #print (z0.__repr__())
69 #print (z0.arg())
70 print (abs(z0))
71 #print (z1+z0)
72 print (z0[1],z0[2])
73 # print (z0[3])
74 z0[1]=1953
75 print (z0)
76 print (inv(z0), z0.inv())
77 print (conj(z0), z0.conj())
Solution 72 Mthodes spciales
1 >>> class A : pass
2 ...
3 >>> a=A()
4 >>> def p(x) : return "hello"
5 ...
6 >>> setattr(A,'__str__',p)
7 >>> print (a)
8 hello
Linstruction >>> setattr(A,'__str__',p) attache la mthode spciale __str__() la classe
A. Or, lorsque linstruction >>> print (a) est excute, cest cette mthode spciale (mthode
de classe) qui est automatiquement appele. TODO
Solution 73 Property
Todo
Solution 74
1 def tests(classe, n=10000000) :
2 for i in range(n) : classe()
3
4 import cProfile
5 print("######## SLOTS ##########")
6 cProfile.run('tests(A)')
7 print("######## NO SLOTS ##########")
8 cProfile.run('tests(B)')
CHAPITRE 7
La bibliothque standard
La bibliothque standard de Python est extrmement fournie. Elle propose, rpartis en une qua-
rantaine de thmes, environ 300 modules trs fiables.
De part leur compacit, et leur appartenance la bibliothque standard, ces modules sont utiliss,
tests et dbogus par la communaut Python entire, ce qui garantit leur fiabilit, la diffrence
de certains gros packages spcialiss comme Apache, Django, PySide, etc. dont le dbogage est
plus ardu du fait de leur taille et de leur relative confidentialit.
Parmi les thmes abords dans la bibliothque standard, citons :
les fonctions, les types, les exceptions et les constantes builtins ;
les types de donnes labors (calendriers, dates, tableaux, conteneurs etc.) ;
les chanes de caractre (unicode, expressions rgulires, etc.) ;
les modules mathmatiques et numriques (fonctions mathmatiques, fractions, nombres ala-
toires, etc.) ;
laccs aux fichiers et rpertoires (manipulation de chemins, parcours darborescence, fichiers
temporaires, etc.) ;
la compression de donnes (tar, bzip2, zip, etc.) ;
la persistance de donnes (bases de donnes, sauvegarde, etc.) ;
les markup languages (XML, HTML, etc.) ;
les systmes dexploitation (accs et modification des donnes des OS, etc.) ;
les systmes dexploitation spcifiques (Unix, MacOS, MS Windows, etc.) ;
internet (email, mime, http, ftp, telnet etc.) ;
le multimedia (wave, oss, aif, etc.) ;
linterface graphique Tkinter
les outils pour le dveloppement (langages, debogage, profilage, tests unitaires, etc.) ;
dautres encore ...
Avant de dvelopper votre propre code pour traiter dun problme, consultez la documenta-
tion,vous y trouverez probablement un ou plusieurs modules pour vous faciliter la vie.
On dcrit ici les modules les plus utiles pour la programmation et le calcul scientifique.
7.1. Le module os
Contient de nombreuses facilits pour interagir avec les commandes du systme dexploitation.
178 Chapitre 7. La bibliothque standard
Nutilisez pas from os import * mais prfrez lui import os. Sinon la fonction os.open()
masquera la fonction intgre open(). Toutes deux ont un fonctionnement diffrent.
7.1.1. Le module os.path. Traite de tout ce qui concerne les chemins (path). Il est vivement
conseill dutiliser ce module pour composer ou dcomposer des chemins. Lutilisation du module
os.path assure la portabilit de vos programmes Python dun environnement lautre (MacOs,
Windows, Linux, etc.).
contrario, si vous assemblez un chemin comme /home/puiseux/devel/main.cxx, soyez as-
surs que le programme sera inexploitable sous Windows.
Vous devriez plutt crire os.path.join('home','puiseux','devel','main.cxx').
Les principales fonctions et attributs du module os.path sont les suivantes :
curdir est le nom du rpertoire courant,
sep est le caractre sparateur de chemin. En Unix, cest le / (slash) et en MS Windows le
\ (antislash).
abspath(chemin) retourne le path absolu du paramtre chemin :
1 >>> abspath('toto.cxx')
2 /home/devel/toto.cxx'
basename(chemin) retourne le nom de fichier du paramtre chemin :
1 >>> basename('/home/devel/toto.cxx')
2 'toto.cxx'
dirname(chemin) retourne le nom du rpertoire contenant chemin :
1 >>> dirname('/home/devel/toto')
2 '/home/devel'
3 >>> dirname('/home/devel/toto/')
4 '/home/devel/toto/'
expanduser(chemin) expansion du ~, le rpertoire utilisateur (le contenu de la variable den-
vironnement $HOME en Unix),
getatime(fichier) retourne la date de cration dun fichier,
getsize(fichier) retourne la taille dun fichier,
exists(chemin) retourne True ou False suivant que chemin existe (rpertoire, fichier ou
lien),
isabs(chemin) retourne True ou False suivant que chemin est ou nest pas un chemin
absolu,
isdir(chemin) retourne True ou False suivant que chemin un rpertoire,
isfile(chemin) retourne True ou False suivant que chemin un fichier,
islink(chemin) retourne True ou False suivant que chemin un lien,
ismount(chemin) retourne True ou False suivant que chemin un point de montage,
7.2 Le module sys 179
join(liste) pour reconstituer un chemin partir de ses composants contenus dans liste :
1 >>> os.path.join('devel','toto.cxx')
2 'devel/toto.cxx'
splitext(chemin) renvoit chemin spar en (un tuple ) deux lments, dont le second
lment est lextension, y compris le point :
1 >>> splitext('formations/python.pdf')
2 ('formations/python', '.pdf')
split(chemin) renvoit un tuple (head,tail) dont le second lment tail est ce qui suit
le dernier slash (ou antislash sur MS Windows) ; tail peut tre vide :
1 >>> split('formations/python.pdf')
2 ('formations', 'python.pdf')
7.1.2. Autres services du module os. Le module os fournit de nombreuses autres fonctions.
Les plus utiles sont listes ci-aprs :
system(cmd) excute de la commande shell prcise dans la chane de caractres cmd :
1 >>> os.system('mkdir toto')
walk() permet de parcourir une arborescence :
1 >>> for root,dir,files in os.walk('.') :
2 ... print ("Fichiers du rpertoire %s => %s"%(root,files))
3 ...
divers utilitaires :
1 >>> os.getcwd()
2 >>> os.chdir('~/devel/python')
7.2. Le module sys
Contient des attributs caractristiques de la plateforme, ainsi que quelques fonctions de bas ni-
veau.
sys.path est la liste des path dans lesquels seront recherchs les modules lors dun import ;
sys.modules est la liste des modules disponible sur votre configuration ;
sys.platform est votre plateforme (linux, ...) ;
sys.argv est la liste des arguments actuels de la ligne de commande ;
180 Chapitre 7. La bibliothque standard
sys.float_info est une liste contenant des information sur la reprsentation des nombre
rels ;
sys.stdin, sys.stdout et sys.stderr sont des fichiers reprsentant les entre et sortie
standard et la sortie erreur :
1 >>> sys.stdout.write('Hello\n')
Il peuvent tre redirigs vers un fichier texte :
1 >>> out = sys.stdout #sauvegarde
2 >>> sys.stdout=open('testttt','a')
3 >>> print('hello')
4 >>> a=1
5 >>> a
6 >>> sys.stdout.close()
7 >>> a
8 Traceback (most recent call last) :
9 File "<input>", line 1, in <module>
10 ValueError : I/O operation on closed file
11 >>> sys.stdout=out
12 >>> a
13 1
14 >>>
La commande print autorise une syntaxe plus lgante pour rediriger la sortie standard sur
un fichier texte :
1 >>> f = open('toto.txt','w')
2 >>> print >> f, 'hello'
sys.exit() permet de terminer inconditionnellement un script Python.
7.3. Dates et heures TODO
Le module datetime fournit des classes pour manipuler les dates et les heures aussi bien de
manire simple que de manire complexe. Bien que larithmtique des dates et des heures est
supporte, le centre dattention de limplmentation a t port sur lefficacit de lextraction des
membres en vue de la mise en forme et du traitement de laffichage. Ce module supporte aussi
les objets lis aux fuseaux horaires.
1 >>> from datetime import date
2 >>> now = date.today()
3 >>> now
4 >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B."
)
7.4 Fichiers 181
5 >>> birthday = date(1964, 7, 31)
6 >>> age = now - birthday
7 >>> age.days
7.4. Fichiers
7.4.1. Le module glob. fournit des fonctions pour construire des listes de fichiers partir de
recherches avec jockers dans des rpertoires :
dans le rpertoire courant avec glob(),
dans un autre rpertoire avec glob1() ;
1 >>> import glob
2 >>> glob.glob('*.py')
3 ['primes.py', 'random.py', 'quote.py']
4 >>> glob.glob1('.','*.py')
5 ['primes.py', 'random.py', 'quote.py']
7.4.2. Le sous module glob.fnmatch. permet deffectuer des tches analogues :
glob.fnmatch.filter(names, pat) pour filtrer dans la liste names les noms des fichiers
correspondant lexpression rgulire pat :
1 >>> glob.fnmatch.filter(os.listdir('.'),'*.py')
glob.fnmatch.fnmatch(names, pat) est analogue filter, mais le pattern est en style
Unix, la casse nest pas prise en compte ;
glob.fnmatch.fnmatchcase : idem, la casse est prise en compte ;
glob.fnmatch.translate(pat) transforme un pattern Unix en expression rgulire.
7.4.3. Le module shutil. fournit une interface de haut niveau pour les tches courantes de
gestion de fichiers et rpertoires :
copy(src,dest) copie les donnes et les modes (rwx) du fichier src vers le fichier dest ;
copyfile(src,dest) copie les donnes seulement du fichier src vers le fichier dest ;
copytree(src,dest) recopie rcursive du rpertoire src vers le rpertoire dest ;
move(src,dest) dplace src vers dest, comme la commande Unix mv
rmtree(dir) suppression rcursive de dir.
1 >>> import shutil
2 >>> shutil.copyfile('data.db', 'archive.db')
3 >>> shutil.move('/build/executables', 'installdir')
182 Chapitre 7. La bibliothque standard
7.5. Compression de donnes TODO
Les formats communs pour archiver et compresser des donnes sont supports par des modules,
dont : zlib, gzp, bz2, zipfile et tarfile.
1 >>> import zlib
2 >>> s = u"Sans la liberte de blamer, il n'est point d'eloge
flatteur"
3 >>> len(s)
4 >>> t = zlib.compress(s)
5 >>> len(t)
6 >>> zlib.decompress(t)
7 >>> zlib.crc32(s)
7.6. Arguments de la ligne de commande
Les scripts utilitaires requirent souvent le traitement des arguments de la ligne de commande.
Ces arguments sont stocks sous forme de liste dans lattribut sys.argv :
1 >>> import sys
2 >>> print sys.argv
3 ['demo.py', 'one', 'two', 'three']
Le module getopt traite sys.argv en utilisant les mmes conventions que la fonction Unix
getopt(). En voici un exemple avec des options courtes :
1 >>> import getopt
2 >>> args = '-a -b -ctoto -d bar a1 a2'.split()
3 >>> args
4 ['-a', '-b', '-ctoto', '-d', 'bar', 'a1', 'a2']
5 >>> optlist, args = getopt.getopt(args, 'abc :d :')
6 >>> optlist
7 [('-a', ''), ('-b', ''), ('-c', 'toto'), ('-d', 'bar')]
8 >>> args
9 ['a1', 'a2']
et avec les options longues :
1 >>> s = '--condition=foo --test --output-file abc.def -x a1 a2'
2 >>> args = s.split()
3 >>> args
4 ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x',
'a1', 'a2']
7.7 Mesure des performances 183
5 >>> optlist, args = getopt.getopt(args, 'x', [
6 ... 'condition=', 'output-file=', 'testing'])
7 >>> optlist
8 [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc
.def'), ('-x', '')]
9 >>> args
10 ['a1', 'a2']
Un traitement de la ligne de commande plus puissant est fourni par le module argparse
1
Pour lutiliser on commence par importer et instancier argparse.ArgumentParser :
1 from optparse import ArgumentParser
2 parser = ArgumentParser(description='Ajouter des entiers.')
puis dcrire les options attendues :
1 parser = argparse.ArgumentParser(description='Process some
integers.')
2 parser.add_argument('entiers', metavar='N', type=int, nargs='+',
3 help='oprer sur deux entiers')
7.7. Mesure des performances
7.7.1. Le module time. Permet de mesur le temps coul et le temps CPU (le temps pass
par un processus en mmoire centrale) :
time() mesure le temps ordinaire, celui de lhorloge
clock() donne le temps CPU consomm par le processus Pythonactuel depuis le dbut de
son excution.
1 >>> import time
2 >>> e0 = time.time() # elapsed time since the epoch
3 >>> c0 = time.clock() # total CPU time spent in the script
4 >>> elapsed_time = time.time() - e0
5 >>> cpu_time = time.clock() - c0
1
La documentation Python signale que le module optparse nest plus maintenu et sera remplac par argparse,
dcrit ici.
184 Chapitre 7. La bibliothque standard
7.7.2. Le module timeit. Pour comparer certaines instructions, ou diffrentes options de
programmation sur des portions de code de taille rduite, on peut utiliser le module timeit.
Ce module contient principalement la classe Timer dont le constructeur est
Timer(stmt='pass', setup='pass').
Largument stmt est la squence dinstructions chronomtrer. Les instructions doivent tre
spares par des ;
setup est une instruction dinitialisation, qui sera excute une seule fois avant stmt
Il suffit ensuite dinvoquer la mthode timeit(number=1000000) qui excute et chronomtre
number fois linstruction stmt du constructeur, aprs excution de linitialisation setup.
Lexemple qui suit chronomtre la suite dinstructions w = x ; x = y ; y = w aprs initiali-
sation x = 1 ; x = 2 :
1 >>> from timeit import Timer
2 >>> t = Timer('w = x ; x = y ; y = w', 'x = 1 ; y = 2')
3 >>> t.timeit()
4 0.059217929840087891
Il est intressant de comparer ce rsultat avec celui de linstruction suivante :
1 >>> t = Timer('x, y = y, x', 'x, y = 1, 2')
2 >>> t.timeit()
3 0.035509824752807617
Pour permettre au module timeit daccder une fonction, il suffit de limporter lors de linitia-
lisation :
1 def test() :
2 "Stupid test function"
3 L = []
4 for i in range(100) :
5 L.append(i)
6
7 if __name__=='__main__' :
8 from timeit import Timer
9 t = Timer("test()", "from __main__ import test")
10 print t.timeit()
7.7 Mesure des performances 185
7.7.3. Les modules profile, cProfile et pstats. Pour profiler des (portions de) codes plus
importants, il est prfrable dutiliser les modules profile ou cProfile et pstats.
Les modules profile et cProfile proposent une interface utilisateur analogue. La doc de Py-
thon recommande dutiliser plutt cProfile, dont l overhead
2
est moins important.
Pour profiler une portion de code, il suffit dappeler la fonction
cProfile.run(command, filename=None, sort=-1)
en lui passant la commande profiler, le nom du fichier rsultat (par dfaut sur la sortie standard)
et lordre daffichage des rsultats (par dfaut sort='stdname', le tri se fait par nom de fichier
et numro de ligne). On peut galement demander le tri des rsultats par nombre dappels (sort
='calls'), par temps dexcution (sort='time') ou par temps dexcution cumul (sort='
cumulative').
Dans lexemple qui suit, on applique une fonction donne tous les termes dune (grande) liste
numrique, on utilise la fonction map() ou bien une technique de liste en comprhension. Voici
un moyen pour comparer les temps dexcution de ces deux mthodes :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import random,cProfile
4 from math import sin
5 N=1000
6 biglist = [random.randint(-100,100) for i in range(N)]
7
8 def myFunction(x) :
9 return sin(x/2.0)
10 def map_without_list_comprehension() :
11 for i in range(100) :
12 list(map(myFunction, biglist))
13 def map_with_list_comprehension() :
14 for i in range(100) :
15 [myFunction(j) for j in biglist]
16
17 print ("===== map_without_list_comprehension =====")
18 cProfile.run('map_without_list_comprehension()')
19 print ("===== map_with_list_comprehension =====")
20 cProfile.run('map_with_list_comprehension()')
on obtient le rsultat suivant
3
:
2
cest dire le temps dexcution des fonctions de mesure du temps
3
Le mme test, avec le module profile au lieu de cProfile, affiche des temps dexcution multiplis par 2.5
environ.
186 Chapitre 7. La bibliothque standard
===== map_without_list_comprehension =====
200004 function calls in 0.528 CPU seconds
Ordered by : standard name
ncalls tottime percall cumtime percall filename :line-
no(function)
[...]
100000 0.259 0.000 0.385 0.000 listcomprehension-
test.py :8(myFunction)
100000 0.126 0.000 0.126 0.000 {built-in method sin}
[...]
===== map_with_list_comprehension =====
200104 function calls in 0.532 CPU seconds
Ordered by : standard name
ncalls tottime percall cumtime percall filename :line-
no(function)
[...]
100 0.145 0.001 0.531 0.005 listcomprehension-
test.py :16(<listcomp>)
100000 0.257 0.000 0.386 0.000 listcomprehension-
test.py :8(myFunction)
[...]
100000 0.129 0.000 0.129 0.000 {built-in method sin}
[...]
Si lon sauvegarde le rsultat dans un fichier, celui-ci peut ensuite tre exploit et prsent, com-
bin avec dautres ou seul, en utilisant la classe Stats du module stats dont les principales
mthodes sont :
Stats(fichier) est le constructeur avec le nom du fichier
add(*filenames) ajoute des fichiers prsenter.
strip_dirs() pour prsenter les statistiques avec des noms de fichier courts (le nom de base
du fichier seulement). Retourne linstance Stats
sort_stats(*keys) trie les statistiques suivant un ordre dfini (voir le paramtre sort de
cProfile.run()). Retourne linstance de Stats
print_stats(*restrictions) affiche les statistiques avec des restrictions sur le nombre
de lignes ou de fonctions affiches.
dump_stats(filename) sauvegarde les statistiques dans le fichier filename
Voici un exemple dutilisation :
1 import pstats, cProfile
2 import polygone
3 cProfile.run('polygone.go0()','go0.prof')
4 cProfile.run('polygone.go1()','go1.prof')
7.8 Calcul scientifique 187
5 s = pstats.Stats()
6 s.add('go0.prof','go1.prof')
7 s.strip_dirs().sort_stats("time").print_stats()
Contrle de qualitTODO
Nous avons dja dit quelque mots, au paragraphe 2.12 page 45 propos de la programmation
dirige par la documentation et le module doctest. Sur ce sujet, et sur le dveloppement de
projets informatiques, la lecture de lexcellent ouvrage [TZ] est fortement recommande.
7.7.4. Le module unittest TODO. Cest un module plus contraignant que doctest, mais il
permet de maintenir dans un fichier spar des tests plus tendus.
1 import unittest
2 class TestStatisticalFunctions(unittest.TestCase) :
3 def test_average(self) :
4 self.assertEqual(average([20, 30, 70]), 40.0)
5 self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
6 self.assertRaises(ZeroDivisionError, average, [])
7 self.assertRaises(TypeError, average, 20, 30, 70)
8 unittest.main() # Calling from the command line invokes all tests
7.8. Calcul scientifique
Les packages NumPy et SciPy, de loin les plus populaires pour le calcul scientifique, ne sont pas
actuellement disponibles en Python 3.
On examinera plus en dtail les paquetages ddis au calcul scientifique en Python 2 au chapitre 8
page 197.
7.8.1. Le module math. Le module math donne accs aux fonctions mathmatiques vir-
gule flottante de la bibliothque Csous-jacente. La liste des fonctions et constantes disponibles
est la suivante :
Constantes.
e la constantes e = exp (1) 2.718281828459045
pi la constante 3.141592653589793
Conversion.
degrees(x) convertit x de radians en degr et
radians(x) convertit x de degrs en radians.
188 Chapitre 7. La bibliothque standard
Fonctions trigonomtriques et inverses.
sin(x), cos(x), tan(x) retournent sin (x), cos (x) et tan (x), largument est en radians.
hypot(x, y) retourne
x
2
+ y
2
asin(x), acos(x) sont les fonctions inverses des fonctions sin et cos. Lvent lexception
ValueError si |x| > 1
atan(x) la fonction inverse de tan.
atan2(x, y) retourne arctan
(
y
x
)
si x = 0 et
2
si x = 0.
Fonctions hyperboliques et inverses.
cosh(x), sinh(x) et tanh(x) retournent les cosinus hyperbolique, sinus hyperbolique, et
tangente hyperbolique de x. Lexception ValueError est leve si x nappartient pas aux do-
maines de dfinition.
acosh(x), asinh(x), atanh(x) sont le fonctions hyperboliques inverses des prcdentes.
Fonctions diverses.
ceil(x) retourne min{n Z, n x} ;
floor(x) retourne max {n Z, n x} ;
trunc(x) retourne x tronqu au point dcimal.
copysign(x,y) retourne x avec le signe de y ;
fmod(x,y) retourne le reste de la division de x par y, cest dire xny o n Zest lunique
entier vrifiant |r| < |y| et signe (y) = signe (r). Utiliser cette fonction si x et y sont rels
(plus prcis) ; lui prfrer x%y pour x et y entiers (plus rapide) ;
modf(x) retourne la partie fractionnaire et entire de x. Par exemple
1 >>> modf(pi)
2 (0.14159265358979312, 3.0)
fabs(x) retourne la valeur absolue de x ;
fsum(iterable) retourne la somme des items de iterable, tout comme la fonction intgre
sum(iterable), mais le calcul est plus prcis ;
isfinite(x) retourne False si x est infini ou NaN, True sinon ;
isnan(x) retourne True si x est Nan, False sinon ;
isinf(x) retourne True si x est infini (positif ou ngatif), False sinon ;
Fonctions logarithme, exponentielle et fonctions spciales.
frexp(x) retourne la mantisse et lexposant de x sous la forme dun couple (m, e) o m est
un rel et e un entier tels que x = m2
e
et
1
2
|m| < 1. Retourne (0.0, 0) si x vaut 0 ;
factorial(n) retourne n! pour n N. Lve lexception ValueError si n / N;
ldexp(x,n) retourne x 2
n
. Cest linverse de la fonction frexp().
erf(x) retourne la fonction derreur de x, cest dire
2
x
0
e
t
2
dt,
erfc(x) retourne la fonction derreur complmentaire de x dfinie par erfc (x) = 1 erf (x)
exp(x) retourne e
x
7.8 Calcul scientifique 189
expm1(x) retourne e
x
1 calcul avec une prcision accrue lorsque x est proche de 0.
gamma(x) retourne limage par la fonction gamma du rel x, cest dire (x) =
0
t
x1
e
t
dt
qui vrifie (n + 1) = n! pour n N
lgamma(x) retourne ln (|(x)|).
log(x, base=e) retourne le logarithme de x de base base, cest dire
ln(x)
ln(base)
. Lve lex-
ception ValueError si x 0
log10(x) retourne log(x,10)
log1p(x) retourne ln(1 + x). Lorsque x est voisin de 0, le calcul est raffin.
pow(x, y) retourne x
y
. pow(1.0, y) et pox(x, 0.0) retournent 1 dans tous les cas. Lex-
ception ValueError et leve si x < 0 et y / Z
sqrt(x)retourne la racine carre de x. Lexception ValueError est leve si x < 0.
Quelques exemples dutilisation
.
1 >>> from math import *
2 >>> cos(pi / 4.0)
3 0.7071067811865476
4 >>> log(1024, 2)
5 10.0
7.8.2. Le module cmath. Contient des fonctions analogues celles du module math, mais
ddies aux nombres complexes, ainsi que les fonctions suivantes :
phase(z) retourne largument du complexe z ;
polar(z) retourne le couple module, argument des coordonnes polaires du complexe z ;
rect(r,teta) retourne le complexe z dont les coordonnes polaires sont r et teta.
La dtermination des fonctions log() et trigonomtriques inverses asin(), acos(), etc. corres-
pondent au plan complexe muni de la coupure , cest dire le demi-axe des x ngatifs. Voir la
documentation Python.
7.8.3. Le module random. Le module random fournit des outils pour faire des slections
alatoires :
random() retourne un rel alatoire dans lintervalle [0, 1] ;
randint(a, b) retourne un entier alatoire dans lintervalle [a, b] ;
randrange(a,b) retourne un entier alatoire dans lintervalle [a, b[ ;
choice(seq) choisi un lment alatoirement dans la squence seq ;
shuffle(liste) mlange in situ les lments de la liste ;
sample(population, k) choisit un chantillon de k individus unique dans la squence
population ;
190 Chapitre 7. La bibliothque standard
gauss(mu, sigma) retourne un rel alatoire suivant une distribution de Gauss de moyenne
mu et dcart type sigma ; dautre distributions sont proposes avec les mthodes : lognormvariate
(), betavariate(), normalvariate(), expovariate(), gammavariate(), paretovariate
(), vonmisesvariate(), triangular(), uniform(), weibullvariate().
Exemple dutilisation :
1 >>> import random
2 >>> random.choice(['apple', 'pear', 'banana'])
3 'apple'
4 >>> random.sample(xrange(100), 10)
5 [55, 59, 52, 33, 66, 44, 78, 58, 62, 6]
6 >>> random.random()
7 0.27695553082643876
8 >>> random.randrange(6)
9 1
10 >>> l=range(-2,4)
11 >>> random.shuffle(l)
12 >>> l
13 [3, 1, -2, -1, 0, 2]
7.8.4.
7.9. Autres modules
urllib2 et smtplib sont deux modules des plus simples pour rcuprer des donnes depuis
des url et pour envoyer du courrier :
1 >>> import urllib2
2 >>> for line in urllib2.urlopen('http ://tycho.usno.navy.mil/
cgi-bin/timer.pl') :
3 ... if 'EST' in line : # look for Eastern Standard Time ...
4 print line <BR>Nov. 25, 09 :43 :32 PM EST
5 >>> import smtplib
6 >>> server = smtplib.SMTP('localhost')
7 >>> server.sendmail('[email protected]', 'jcaesar@example.
org',
8 """To : [email protected]
9 From : [email protected]
10 Beware the Ides of March.
11 """)
12 >>> server.quit()
7.9 Exercices TODO 191
Le paquetage email pour grer les messages lectroniques, y compris les documents MIME
et les autres documents bass sur la RFC-2822. Contrairement smtplib et poplib, qui
envoient et reoivent effectivement des messages, le paquetage email a une bote outils
complte pour construire ou dcoder des messages la structure complexe (incluant des pices
jointes) et pour le codage et les enttes.
Les paquetages xml.dom et xml.sax fournissent un support robuste pour analyser ces formats
dchange de donnes trs rpandus. De mme, le module csv effectue des lectures et des
critures directement dans un format de base de donnes commun.
Linternationalisation est supporte par un certain nombre de modules, incluant les paquetages
gettext, locale et codecs.
Le module re fournit des outils dexpressions rgulires pour un traitement avanc des chanes.
Pour des appariements et des traitements complexes, les expressions rgulires offrent des so-
lutions succinctes et optimises :
1 >>> import re
2 >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
3 >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
Lorsque seules des oprations simples sont requises, les mthodes des chanes sont pr-
frables car elles sont plus simples lire et dbugger :
1 >>> 'tea for too'.replace('too', 'two')
Exercices TODO
Exercice 75. os et os.path
(1) Retournez la liste des fichiers du rpertoire courant (module os)
(2) Lister rcursivement ladresse absolue de tous les fichiers .py et .txt qui sy trouvent.
Exercice 76. Parcours de rpertoires. (utiliser os.walk() et os.path) loccasion dun im-
portant backup de sa photothque, un photographe veut sassurer que toutes ses images ont bien
t sauvegardes. Il cre une liste des rpertoires et des fichiers contenus avec la taille en octets,
dans le dossier dorigine, puis dans le dossier de sauvegarde. Il compare ensuite les deux listes
ainsi constitues et affiche les diffrences.
(1) crire un script Python walk.py, qui prend comme argument un rpertoire, en parcourt r-
cursivement tous les sous rpertoires, et liste lcran sous la forme (nomfichier, taille
), tous les fichers dont lextension est dans la liste
1 IMAGES = ('.jpg', '.jpeg', '.tiff', '.tif', '.gif',
2 '.bmp', '.png', '.svg', '.xcf', '.mov',
3 '.mp3', '.mp4', '.mpeg', '.mpg', '.avi', '.cr2')
La liste sera trie avant affichage ;
192 Chapitre 7. La bibliothque standard
(2) excuter ce script depuis le rpertoire photothque dorigine, et depuis le rpertoire backup
et produire deux fichiers list.txt et listbakup.txt. La commande Unix $ walk.py >
list.txt permet de rediriger laffichage dans le fichier list.txt ;
(3) crire une fonction qui prend en entre les deux fichiers list.txt et listbakup.txt crs,
parcourt list.txt ligne par ligne, vrifie que chaque fichier list se trouve dans le fichier
listbakup.txt avec la bonne taille. Sil ne sy trouve pas, ou si sa taille nest pas identique,
afficher un message.
Exercice 77. Modules standards
(1) Calculez le cosinus de pi/2 (module math) ;
(2) crivez la racine carre des nombres de 10 20 (module math) ;
(3) gnrez une squence alatoire de 20 entiers tirs entre 1 et 4 (module random) ;
(4) crivez les nombres de 1 5 avec 3 secondes dintervalle (module time) ;
(5) faites afficher la date du jour (time) ;
(6) dterminez votre jour (lundi, mardi...) de naissance (module calendar).
(7) Trouver ladresse absolue de votre rpertoire utilisateur (module os.path).
(8) Retournez la liste des fichiers du rpertoire courant (fonction os.system() )
Exercice 78. Tri
(1) Trouver la liste des codes ASCII des caractres imprimables (utiliser le module string)
(2) Crer une liste alatoire L de N = 100 caractres ASCII imprimables (utiliser le module
random)
(3) Transformer cette liste en chane de caractres C.(utiliser la mthode str.join()).
(4) Est-il possible de trier cette chane in situ ? Pourquoi ?
(5) Crer une nouvelle chane C contenant les caractres de C tris.
(6) Crer une nouvelle chane C contenant les caractres de C tris indpendamment de la casse.
(Utiliser largument key de sorted() et la mthode str.lower())
Exercice 79. Mesure de performances.
(1) Tester laide du module cProfile la vitesse dexcution des diffrentes mthodes de calcul
du produit scalaire, proposes lexercice 20 page 70
(2) Idem pour le produit matriciel propos lexercice 21 page 70
Solutions des exercices
Solution 75 os et os.path
(1) Adresse absolue dun chemin >>> os.path.abspath('.')
(2) contenu du rpertoire courant : deux solutions
>>> os.system('ls')
>>> os.listdir('.')
(3) Lister rcursivement le contenu dun rpertoire
7.9 Solutions des exercices 193
1 >>> racine = '~/devel/Version2/Concha/'
2 >>> for r,d,F in os.walk(racine) :
3 ... for f in F :
4 ... if os.path.splitext(f)[1] in ('.py','.txt') :
5 ... print os.path.basename(f)
Solution 76 os.walk et os.path
(1) La fonction findFiles() trouve toutes les images dans le rpertoire et ses sous rpertoires,
et en retourne la liste. noter que lon supprime les points dans lextension des fichiers par
strip('.') et que lon convertit lextension en minuscule avec lower(), ce qui permet de
ne pas oublier les fichiers avec extension Jpeg ou MPEG
1 #!/usr/bin/python
2 import sys, os
3 IMAGES = ('jpg','jpeg','tiff','tif','gif',
4 'bmp','png','svg','xcf','mov',
5 'mp3','mp4','mpeg','mpg','avi','cr2','pcd')
6
7 def findFiles(mainroot='', exts = IMAGES) :
8 liste = []
9 for root, dirs, files inos.walk(mainroot) :
10 for file in files :
11 if os.path.splitext(file)[1].strip('.').lower() in
exts :
12 af = os.path.join(root,file)
13 size = os.path.getsize(af)/(1024.0**2)
14 liste.append((af, size))
15 return liste
16
17 if __name__ == '__main__' :
18 try : root = sys.argv[1]
19 except IndexError : root = '.'
20 exts = IMAGES
21 liste = findFiles(root, exts)
22 for image,size in sorted(liste) :
23 print('{0} => {1 :.2f} Mo'.format(image,size))
(2) La comparaison des listes peut se faire laide de la fonction compare() que voici :
1 def compare (file1, file2) :
2 list2 = [line.strip().split('=>') for line in open(file2).
readlines()]
194 Chapitre 7. La bibliothque standard
3 for line in open(file1) :
4 line = line.strip().split('=>')
5 if not line in list2 :
6 print('manque {}'.format(line))
Solution 77 Modules standards
(1) cosinus
1 >>> from math import cos, pi
2 >>> print(cos(pi/2))
;
(2) racines carres
1 >>> from math import sqrt
2 >>> print([sqrt(n) for n in range(10,21)])
3 [3.1622776601683795, 3.3166247903553998, 3.4641016151377544,
4 3.6055512754639891, 3.7416573867739413, 3.872 983346207417,
5 4.0, 4.1231056256176606, 4.2426406871192848, 4.358898943540674,
6 4.4721359549995796]
;
(3) nombres alatoires
1 >>> a=range(1,5)
2 >>> for i in range(20) :
3 ... print(random.choice(a),)
4 2 2 4 1 3 1 3 4 3 3 1 4 4 1 2 2 3 3 4 1
;
(4) affichage intervalle rgulier
1 >>> for i in range(5) :
2 ... i
3 ... time.sleep(3)
;
(5) date du jour :
1 >>> import time
2 >>> time.localtime()
ou encore
7.9 Solutions des exercices 195
1 >>> from datetime import date
2 >>> date.today()
;
(6) jour de naissance
1 >>> calendar.weekday(1953,12,02)
(7) Adresse absolue dun chemin
1 >>> os.path.abspath('.')
(8) Liste des fichiers du rpertoire courant
1 >>> os.listdir('.')
Solution 78 Tri
(1) >>> P = string.printable
(2) >>> L = [P[random.randint(0,len(P))] for i in range(N)]
(3) >>> C = ''.join(L)
(4)
1 >>> C.sort()
2 Traceback (most recent call last) :
3 [...]
4 AttributeError : 'str' object has no attribute 'sort'
(5) >>> ''.join(sorted(C, key=str.lower))
Solution 79 (1) Produit scalaire :
1 # -*- coding : utf-8 -*-
2 import random
3 import cProfile as prof
4
5 N = 1000000
6 U = [random.random() for i in range(N)]
7 V = [random.random() for i in range(N)]
8
9 def dot0(X,Y) :
10 s = 0
11 for i in range(N) :
12 s += X[i]*Y[i]
13
14 def dot1(X,Y) :
196 Chapitre 7. La bibliothque standard
15 sum([x*y for x,y in zip(X,Y)])
16
17 def dot2(X,Y) :
18 sum(x*y for x,y in zip(X,Y))
19
20 print ("===== dot la C =====")
21 prof.run('dot0(U,V)')
22 print ("===== dot liste =====")
23 prof.run('dot1(U, V)')
24 print ("===== dot gnrateur =====")
25 prof.run('dot2(U,V)')
En Python 2.6 on obtient le rsultat suivant (extrait) :
===== dot la C =====
4 function calls in 0.245 CPU seconds
===== dot liste =====
5 function calls in 1.291 CPU seconds
===== dot gnrateur =====
1000006 function calls in 3.498 CPU seconds
En Python 3.1 on obtient une nette amlioration :
===== dot la C =====
4 function calls in 0.265 CPU seconds
===== dot liste =====
6 function calls in 0.183 CPU seconds
===== dot gnrateur =====
1000006 function calls in 2.449 CPU seconds
CHAPITRE 8
Python pour le calcul scientifique
Suivant le lien http://www.scipy.org/Topical_Software, on trouvera une liste assez com-
plte de packages scientifiques Python dans diffrents domaines dapplication.
On relira avec profit la section 7.7 page 183
8.1. NumPy
Cette partie est largement inspire du tutoriel http://www.scipy.org/Tentative_NumPy_Tutorial
NumPy est un package Python , disponible pour les versions 2.x seulement, dont le but principal
est le traitement des tableaux multidimensionnels, homognes, cest dire des tableaux multi-
indexs, dlments de mme type. Par exemple des vecteurs, matrices, images, ou feuilles de
calcul.
Un tableau multidimensionnel possde plusieurs dimensions ou axes. Le terme dimension est
ambigu, aussi nous parlerons plutt de tableau multi-axes en cas dambiguit. Dans un tableau
multi-axes, les items sont reprs par des coordonnes entires, cest pourquoi le terme multi-axes
est plus adapt.
Par exemple, un vecteur na quun seul axe, les items y sont reprs par leur position cest dire
leur unique coordonne entire.
Une matrice possde deux axes, ses lments sont reprs par deux coordonnes entires. Pour
une matrice A = (a
i,j
)
1im
1jn
llment a
i,j
a pour coordonnes entires i et j, la notation NumPy
est A[i,j]. Les entiers n et msont les dimensions de la matrice suivant les deux axes. En NumPy,
on dira plutt que la forme (shape) de la matrice est (m, n).
8.1.1. Mthodes et fonctions de NumPy.
Cration de tableaux : arange, array, copy, empty, eye, fromfile, fromfunction, identity
, linspace, logspace, mgrid, ogrid, ones, r_ , zeros, zeros_like ;
conversions : astype, atleast, mat ;
manipulations : split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit
, hstack, item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take,
transpose, vsplit, vstack ;
requtes boolennes : all, any, nonzero, where ;
ordre : argmax, argmin, argsort, max, min, ptp, searchsorted, sort ;
198 Chapitre 8. Python pour le calcul scientifique
oprations : choose, compress, cumprod, cumsum, inner, fill, imag, prod, put, putmask,
real, sum ;
statistique de base : cov, mean, std, var ;
algbre linaire de base : cross, dot, outer, svd, vdot ;
8.1.2. Les bases de Numpy. Les tableaux multidimensionnels NumPy sont reprsents par
la classe numpy.ndarray. ne pas confondre avec la classe array de Python qui ne reprsente
que des tableaux uni-dimensionnels.
Les principaux attributs de la classe ndarray sont :
ndarray.ndim est le nombre daxes (on dit parfois aussi le rang)
ndarray.shape est un tuple dentiers donnant la taille du tableau suivant chaque axe. Le
tuple shape est donc de longueur gale au nombre daxes du tableau, ndim.
ndarray.size est le nombre total dlments du tableau. Cest le produit des termes de shape
. Par exemple, pour une matrice de R
m,n
, size vaut mn.
ndarray.dtype est le type des lments du tableau. Divers types standard Python peuvent
tre spcifis. NumPy propose aussi les types bool_, character, int_, int8, int16, int32,
int64, float_, float8, float16, float32, float64, complex_, complex64, object_.
ndarray.itemsize est la taille en octet de chaque lment du tableau. Par exemple, pour un
tableau de type float64, lattribut itemsize vaut 64/8 = 8.
ndarray.data est le buffer contenant les lment du tableau. On aura rarement besoin dy
accder directement, mais plutt au travers des oprateurs dindexation et de slicing proposs
par NumPy.
ndarray.base est le tableau dorigine si le tableau est une vue ou un slice dun autre tableau.
Sil a t cr ex-nihilo (par exemple avec ndarray.zero()), alors base vaut None.
Exemple :
1 >>> import numpy
2 >>> a = numpy.arange(10)
3 >>> a.shape = (2,5)
4 >>> a
5 array([[0, 1, 2, 3, 4],
6 [5, 6, 7, 8, 9]])
7 >>> a.shape
8 (2, 5)
9 >>> a.dtype.name
10 'int32'
On notera que le package sappelle NumPy, mais que suivant les prconisations de Guido Van
Rossum, le module (nomde fichier) simporte par linstruction import numpy tout en minuscule.
8.1 NumPy 199
8.1.3. Cration de tableaux. NumPy propose de nombreuse mthodes pour crer des ta-
bleaux :
partir dune liste Python , ou dune liste de liste...
1 >>> import numpy as np
2 >>> a = np.array([1,2,3])
3 >>> type(a)
4 <type 'numpy.ndarray'>
5 >>> b = np.array([[1,2,3],[4,5,6]])
6 >>> c = np.array(b)
On peut prciser explicitement le type la cration :
1 >>> a = np.array([1,2,3])
2 >>> a.dtype
3 dtype('int32')
4 >>> b = np.array([1,2,3], dtype='complex')
5 >>> b.dtype
6 dtype('complex128')
7 >>> b
8 array([ 1.+0.j, 2.+0.j, 3.+0.j])
Les fonctions zeros(), ones(), empty(), arange(), linspace() permettent galement la cra-
tion de tableaux :
1 >>> a = np.zeros((2,3))
2 >>> b = np.ones(5,dtype='int')
3 >>> c = np.empty(3)
4 >>> c
5 array([ 5.96597778e-264, 0.00000000e+000, 0.00000000e+000])
6 >>> d = arange(start=5, stop=12, step=2.1) #ou arange(5, 12, 2.1)
7 >>> e = np.linspace(0,1,11)
zeros(shape, dtype), ones() et empty() crent un tableau de la forme donne, rempli de
zros, de uns et non initialiss.
arange(start, stop, step, dtype) renvoie un tableau de nombres galement espacs, de
start stop, non compris, par pas de step, de type dtype.
linspace(start, stop, num, endpoint=True) renvoie un tableau de num nombres gale-
ment espacs, de start stop, dernier point compris.
200 Chapitre 8. Python pour le calcul scientifique
8.1.4. Oprations sur les tableaux. Les oprations, les fonctions sont appliques aux ta-
bleaux lment par lment avec dventuelles restrictions sur la compatibilit des dimensions.
Par exemple, pour appliquer la fonction sinus tous les lments dun tableau :
1 >>> g = np.linspace(0,1,11)
2 >>> a = np.sin(g)
3 >>> a
4 array([ 0. , 0.09983342, 0.19866933, 0.29552021, 0.38941834,
5 0.47942554, 0.56464247, 0.64421769, 0.71735609, 0.78332691,
6 0.84147098])
Les oprations courantes (laddition, le produit etc.) entre deux tableaux sont effectus lment
par lment. La comparaison entre deux tableaux (de mme taille) est possible et renvoie un
tableau boolen de mme taille.
Si lon compare, additionne, multiplie, etc. un tableau par un nombre a, chaque lment du tableau
est compar, additionn, multipli, etc. par a
1 >>> b = np.cos(g)
2 >>> a < b
3 array([ True, True, True, True, True, True, True, True, False,
4 False, False], dtype=bool)
5 >>> a < 0.5
6 array([ True, True, True, True, True, True, False, False, False,
7 False, False], dtype=bool)
Pour faire un produit matriciel, il faut utiliser la fonction dot() ou bien utiliser les classes de
matrices (matrix, voir 8.1.10 page 208)
1 >>> A = array(arange(12)).reshape(3,4)
2 >>> B = array(arange(9)).reshape((3,3))
3 >>> B*A
4 Traceback (most recent call last) :
5 File "<ipython console>", line 1, in <module>
6 ValueError : shape mismatch : objects cannot be broadcast to a
single shape
7 >>> dot(B,A)
8 array([[ 20, 23, 26, 29],
9 [ 56, 68, 80, 92],
10 [ 92, 113, 134, 155]])
11 >>> A = matrix(arange(12)).reshape(3,4)
12 >>> B = matrix(arange(9)).reshape((3,3))
13 >>> B*A
14 matrix([[ 20, 23, 26, 29],
8.1 NumPy 201
15 [ 56, 68, 80, 92],
16 [ 92, 113, 134, 155]])
Lorsque lon effectue une opration sur deux tableaux, de types distincts (mais compatibles pour
cette opration), le rsultat est du type le plus gnral (autrement dit le plus prcis) :
1 >>> a = ones((2,3), dtype=int)
2 >>> b = np.random.random((2,3))
3 >>> c = a+b
4 >>> c.dtype
5 dtype('float64')
Attention toutefois, si lon ajoute un (tableau de) rel(s) b un tableau dentiers a in situ , a
reste de type int :
1 >>> a += 1.5
2 >>> a
3 array([[2, 2, 2],
4 [2, 2, 2]])
On peut sommer les lments dun tableau, trouver le minimum, le maximum, sommer dans une
direction daxe :
1 >>> a = np.random.random((2,3))
2 >>> a
3 array([[ 9.59243730e-01, 1.57245491e-01, 7.87875050e-02],
4 [ 3.31722781e-04, 2.30972784e-01, 9.54687062e-01]])
5 >>> a.sum()
6 2.3812682944516514
7 >>> a.min()
8 0.00033172278084458995
9 >>> a.sum(1) #par ligne (axe 1)
10 array([ 1.19527673, 1.18599157])
8.1.5. Indiage, dcoupage, itrations sur les tableaux. Le slicing (dcoupage) est lart
de dcouper les tableaux. Les tableaux unidimensionnels peuvent tre indexs, dcoups, itrs
comme les squences Python.
Les tableaux multi-dimensionnels sont indexs par des tuples, avec un indice par axe. Les indices
sur chaque axe suivent les mme rgles que les indices de tableau unidimensionnels.
202 Chapitre 8. Python pour le calcul scientifique
1 >>> def f(x,y) :
2 ... return 10*x+y
3 ...
4 >>> b = np.fromfunction(f,(3,4),dtype=int)
5 >>> b
6 array([[ 0, 1, 2, 3],
7 [10, 11, 12, 13],
8 [20, 21, 22, 23]])
9 >>> b[2,3]
10 23
11 >>> b[ :,1]
12 array([ 1, 11, 21])
13 >>> b[ :,2 :3]
14 array([[ 2],
15 [12],
16 [22]])
Il est possible d oublier certains indices en fin de tuple. Dans ce cas, NumPy complte par
autant de ', :' que ncessaire.
Les points de suspension sont remplacs par autant de ', :' que ncessaire.
Exemple :
1 >>> a = arange(24).reshape(3,2,4)
2 >>> a
3 array([[[ 0, 1, 2, 3],
4 [ 4, 5, 6, 7]],
5
6 [[ 8, 9, 10, 11],
7 [12, 13, 14, 15]],
8
9 [[16, 17, 18, 19],
10 [20, 21, 22, 23]]])
11
12 >>> a[0] # idem a[0, :, :]
13 array([[0, 1, 2, 3],
14 [4, 5, 6, 7]])
15 >>> a[...,2] # idem a[ :, :,2]
16 array([[ 2, 6],
17 [10, 14],
18 [18, 22]])
8.1 NumPy 203
Il est possible ditrer sur les lignes (premier axe) dun tableau :
1 >>> a = arange(6).reshape(3,2)
2 >>> for row in a :
3 ... print(row)
4 [0 1]
5 [2 3]
6 [4 5]
Pour itrer sur tous les lments dun tableau, il faut le mettre plat et utiliser lattribut flat
qui est un itrateur sur les items du tableau :
1 >>> a = arange(6).reshape(3,2)
2 >>> for x in a.flat :
3 ... print x,
4 ...
5 0 1 2 3 4 5
Pour parcourir les indices et lments dun tableau, litrateur ndenumerate() fonctionne de
manire analogue enumerate() de Python en retournant les coordonnes entires et la valeur
de chaque lment :
1 >>> a = arange(6).reshape(3,2)
2 >>> for ij,x in ndenumerate(a) : print ij,x
3 ...
4 ...
5 (0, 0) 0
6 (0, 1) 1
7 (1, 0) 2
8 (1, 1) 3
9 (2, 0) 4
10 (2, 1) 5
8.1.6. Remodelage des tableaux. Dans les tableaux NumPy les donnes sont allous dans
une zone de mmoire contige, la forme (nombre et taille des axes) naffecte pas le tableau lui-
mme mais uniquement la manire daccder aux lments. On peut modifier la forme (shape)
de divers manires sans modifier les donnes elle-mmes :
1 >>> a = floor(10*np.random.random((3,2)))
2 >>> a
3 array([[ 5., 6.],
4 [ 1., 1.],
5 [ 5., 1.]])
204 Chapitre 8. Python pour le calcul scientifique
6 >>> a.shape
7 (3, 2)
8 >>> a.ravel()
9 array([ 5., 6., 1., 1., 5., 1.])
10 >>> a.reshape(2,3)
11 array([[ 5., 6., 1.],
12 [ 1., 5., 1.]])
13 >>> a.shape
14 (3, 2) #a non modifi
Sauf demande expresse de lutilisateur (paramtres offset, stride et order de ndarray), Num-
Py cre les tableaux style C ordonns avec le dernier indice variant le plus vite (A[0,0] puis
A[0,1], etc.). Dans ce cas, les fonctions ravel(), reshape() retournent un nouveau tableau
avec les mme donnes, mais avec sa nouvelle forme (sans recopie). Il est cependant possible
de demander aux fonctions ravel() et reshape() de retourner un tableau style FORTRAN
cest dire avec le premier indice variant le plus vite. Dans ce cas, ces fonctions retournent une
recopie du tableau. Dans tous les cas, le tableau lui-mme nest pas modifi.
Le mthode resize() modifie le tableau lui-mme et ne retourne rien :
1 >>> a.resize(1,6)
2 >>> a.shape
3 (1,6)
Dans ces oprations de remodelage, le dernier indice peut prendre la valeur -1, auquel cas NumPy
calcule lui-mme la dernire dimension de sorte que la taille totale (nombre ditems) du tableau
soit inchange.
8.1.7. Empilage de tableaux. Les fonctions et mthodes vstack, hstack, column_stack,
concatenate, c_ et r_ permettent dempiler (stack) les tableaux NumPy suivant les diffrents
axes. Les dimensions doivent tre compatibles.
1 >>> a = np.arange(6).reshape(2,3)
2 >>> a
3 array([[0, 1, 2],
4 [3, 4, 5]])
5 >>> b = np.arange(9).reshape(3,3)
6 >>> b
7 array([[0, 1, 2],
8 [3, 4, 5],
9 [6, 7, 8]])
10 >>> np.vstack((a,b))
11 array([[0, 1, 2],
12 [3, 4, 5],
8.1 NumPy 205
13 [0, 1, 2],
14 [3, 4, 5],
15 [6, 7, 8]])
La fonction concatenate() permet des actions analogues :
1 >>> b = np.arange(4).reshape(2,2)
2 >>> a = np.arange(4).reshape(2,2)
3 >>> np.concatenate((a,b))
4 array([[0, 1],
5 [2, 3],
6 [0, 1],
7 [2, 3]])
8 >>> np.concatenate((a,b),1)
9 array([[0, 1, 0, 1],
10 [2, 3, 2, 3]])
8.1.8. Copies et vues. Lorsque lon manipule des tableaux NumPy, parfois les donnes sont
dupliques, parfois elles ne le sont pas. Cest une source de confusion frquente.
Pas de recopie. Lors dune simple affectation, il ny a aucune recopie :
1 >>> import numpy as np
2 >>> a = np.arange(6)
3 >>> b = a
4 >>> b is a
5 True
Copie de surface. Des tableaux distincts peuvent partager les mmes donnes, sous deux
formes diffrentes ; ce sont deux vues distinctes des mmes donnes. La mthode ndarray.view
() retourne une nouvelle vue sur le tableau, qui partage donc les mmes donnes.
1 >>> v = a.view()
2 >>> v is a
3 False
4 >>> v.base is a
5 True
6 >>> v.shape = 2,3
7 >>> v[0,0] = 314
8 >>> a[0,0]
9 314
206 Chapitre 8. Python pour le calcul scientifique
Un slice de tableau retourne une vue (partielle) sur le tableau. Attention, a nest pas le fonction-
nement ordinaire de Python pour qui un slice retourne une copie de la partie de tableau slice.
1 >>> s = v[ :]
2 >>> s[1,1] = 44444
3 >>> v
4 array([[ 314, 1, 2], [ 3, 44444, 5]])
5 >>> a
6 array([ 314, 1, 2, 3, 44444, 5])
7 >>> s = v[ :1]
8 >>> s[0] = -10
9 >>> a
10 array([ -10, -10, -10, 3, 44444, 5])
Copie profonde. pour faire une recopie profonde du tableau, utiliser la mthode ndarray.
copy() :
1 >>> a = np.arange(6)
2 >>> u = a.copy()
3 >>> u is a
4 False
5 >>> u.base is a
6 False
7 >>> u[0] = 3000
8 >>> a
9 array([0, 1, 2, 3, 4, 5])
8.1.9. Quelques fonctions plus volues. En plus des facilits dindexation avec des entiers
et des slices, Numpy propose lindexation avec des tableaux dindices ou de boolens.
Indexation par liste dentiers. Pour faire rfrence aux lments a
1
, a
1
, a
1
, a
3
, a
10
dun ta-
bleau A = arange(10)**2, il suffit dindexer A par la liste L = [1, 1, 1, 6, 9] ou le tableau
array([1, 1, 1, 6, 9]) (voir lexercice 8.5.5 page 219). On peut utiliser ce mode dindexa-
tion en consultation mais aussi en affectation :
1 >>> L = [1, 1, 1, 6, 9]
2 >>> A[L]
3 np.array([ 1, 1, 1, 36, 81])
4 >>> A[L] = [2, 3, 4, -3, -10]
5 >>> A
6 np.array([ 0, 4, 4, 9, 16, 25, -3, 49, 64, -10])
8.1 NumPy 207
Indexation par liste de boolens. Un tableau de boolen peut tre pass pour indexer un
tableau, dans ce cas, les lments correspondant la valeur True sont extraits du tableau, ceux
indexs par False ne le sont pas. Le tableau extrait est mis plat :
1 >>> a = np.arange(12)
2 >>> a.shape = (3,4)
3 >>> b = a > 4
4 >>> b
5 array([[False, False, False, False],
6 [False, True, True, True],
7 [True, True, True, True]], dtype=bool)
8 >>> a[b]
9 array([ 5, 6, 7, 8, 9, 10, 11])
Il est possible dextraire des lignes ou des colonnes compltes, dans ce cas le tableau rsultant
nest pas remis plat :
1 >>> b1 = np.array([False,True,True])
2 >>> b2 = np.array([True,False,True,False])
3 >>> a[b1, :]
4 array([[ 4, 5, 6, 7],
5 [ 8, 9, 10, 11]])
6 >>> a[ :,b2]
7 array([[ 0, 2],
8 [ 4, 6],
9 [ 8, 10]])
Ce type dindexation est manier avec prcaution. Si lon indexe une liste de boolens au lieu
dun array de boolens, le rsultat est surprenant (bug ? ) :
1 >>> b1 = [False,True,True]
2 >>> b2 = [True,False,True,False]
3 >>> a[b1, :]
4 >>> A[b1, :]
5 array([[0, 1, 2, 3],
6 [4, 5, 6, 7],
7 [4, 5, 6, 7]])
8 >>> a[ :,b2]
9 array([[1, 0, 1, 0],
10 [5, 4, 5, 4],
11 [9, 8, 9, 8]])
12 array([[ 0, 2],
13 [ 4, 6],
208 Chapitre 8. Python pour le calcul scientifique
14 [ 8, 10]])
8.1.10. Algbre linaire de base. NumPy propose quelques oprations dalgbre linaire
lmentaires. Des fonctionnalits plus volues se trouvent dans le module linalg de SciPy, y
compris la manipulation de systmes linaires creux (sparse). Voir 8.2 page suivante.
NumPy propose une classe matrix que lon examine plus loin, ainsi que quelques oprations
dalgbre linaire sur des tableaux :
1 >>> from numpy import *
2 >>> from numpy.linalg import *
3 >>> a = array([[1.0, 2.0], [4.0, 3.0]])
4 >>> a.transpose()
5 array([[ 1., 3.],
6 [ 2., 4.]])
7 >>> inv(a)
8 array([[-0.6, 0.4],
9 [ 0.8, -0.2]])
10 >>> u = eye(2)
11 >>> j = array([[0.0, -1.0], [1.0, 0.0]])
12 >>> dot (j, j)
13 array([[-1., 0.],
14 [ 0., -1.]])
15 >>> trace(u)
16 2.0
17 >>> y = array([[5.], [7.]])
18 >>> solve(a, y)
19 array([[-0.2],
20 [ 2.6]])
21 >>> eig(j)
22 (array([ 0.+1.j, 0.-1.j]),
23 array([[ 0.70710678+0.j , 0.70710678+0.j ],
24 [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))
La classe matrix, une introduction sommaire
1 >>> A = matrix('1.0 2.0; 3.0 4.0')
2 >>> A
3 matrix([[ 1. 2.]
4 [ 3. 4.]])
5 >>> type(A)
6 <class 'numpy.matrixlib.defmatrix.matrix'>
7 >>> A.T
8.4 C/C++ en Python 209
8 matrix([[ 1. 3.]
9 [ 2. 4.]])
10 >>> X = matrix('5.0 7.0')
11 >>> Y = X.T
12 >>> Y
13 matrix([[5.]
14 [7.]])
15 >>> A*Y
16 matrix([[19.]
17 [43.]])
18 >>> print A.I
19 [[-2. 1. ]
20 [ 1.5 -0.5]]
21 >>> solve(A, Y)
22 matrix([[-3.],
23 [ 4.]])
8.2. Scipy
Quelques tches courantes en calcul scientifique :
algebre linaire, scipy.linalg
optimisation, scipy.optimize
integration et quations diffrentielles scipy.integrate
fonctions spciales, scipy.special
transformation de Fourier, scipy.fftpack
traitement du signal et imagerie, scipy.signal
images multidimensionnelles scipy.ndimage
statistiques scipy.stats
entres-sorties scipy.io
inclure du code C dans du code Pythonavec scipy.weave
8.3. Calcul formel avec Sage
http://www.sagemath.org/
8.4. C/C++ en Python
voir http://docs.scipy.org/doc/numpy/user/c-info.python-as-glue.html
210 Chapitre 8. Python pour le calcul scientifique
8.4.1. crire en Python, relire en C++ (binaire). Prenons un exemple concret. Un pro-
gramme C++, une bote noire, disons une simulation numrique, doit lire un maillage dans un
format qui lui est propre. Mais le maillage est disponible dans un format autre. Un programme
Python effectue la conversion de format du maillage, et doit produire un fichier binaire lisible
par le programme C++.
Le format binaire est prfr au format texte pour des raisons de performance en lecture/criture,
le maillage tant trs volumineux.
Le problme est donc de produire en Python un fichier binaire lisible en C++ .
Les mthodes et fonctions classiques de Python permettent dcrire des fichiers texte, ou bien
des fichiers binaires (module pickle) spcifiques Python. Relire ces fichiers en C++ est trs
malcommode.
Le module array. Une solution basique consiste utiliser le module array de Python pour
crire des fichiers binaires directement lisibles en C++ :
1 >>> import array
2 >>> A = array.array('d',range(10))
3 >>> A.tofile(open('myfile.array','wb'))
Ligne 2 : on prcise que A est un tableau de 10 lments de type 'd', cest dire rel double
prcision ;
ligne 3 : le tableau A est crit dans un fichier ouvert en binaire ('wb')
Le programme de lecture en C++ doit connatre exactement le type et le nombre dlements
lire.
Voici un petit programme permettant de vrifier que la lecture en C++ se passe bien :
1 #include <iostream>
2 #include <fstream>
3 using namespace std;
4 int main(){
5 ifstream file("myfile.array",ios ::binary|ios ::in|ios ::ate);
6 int size = (int) file.tellg();
7 file.seekg (0, ios ::beg);
8 double a = 0.0;
9 n = size/sizeof(a);
10 for (int i = 0; i<n ; i++)
11 {
12 file.read((char*)&a,sizeof(a));
13 cout << a << "; ";
14 }
15 cout << endl;
16 file.close();
8.4 C/C++ en Python 211
17 }
Lignes 5-7 : ouverture du fichier en mode binaire (ios ::binary), positionnement en fin de
fichier (ios ::ate), calcul de la taille du fichier en nombre doctets (file.tellg()), reposi-
tionnement en dbut de fichier (ios ::beg) pour lecture.
Ligne 8-9 : les lments sont des rels double prcision, il y en a n lire.
ligne 12 : le C++ est ainsi fait quil faut lire le nombre doctets (char) requis (sizeof(a) octets)
les affecter la variable a sous forme brute. Si lon passe dun systme dexploitation un autre
ou bien dun mode de reprsentation des double prcision un autre, le programme ne fonctionne
plus.
Aprs compilation, et excution, ce programme C++ affiche ce que lon attendait :
1 0; 1; 2; 3; 4; 5; 6; 7; 8; 9;
Le module struct. Il permet de sauvegarder sous forme binaire des donnes htrognes, en
prcisant lendianness
1
. Dans lexemple prcdent supposons que lon ait besoin de stocker plu-
sieurs tableaux la suite dans le mme fichier binaire, en prcisant leurs dimensions. Linstruction
Python suivante retourne sous forme de chane de caractres (doctets) la longueur du tableau A
(len(A)), qui est un entier. ('i')
1 >>> struct.pack('i',len(A))
Dans lexemple ci-dessous, on cre en Python un tableau A (tableau dentiers) et un tableau B
(tableau de rels double prcision).
1 >>> A = array.array('i',range(10))
2 >>> B = array.array('d',range(100,200))
Pour crer un fichier binaire contenant la dimension de A suivie des valeurs de A, suivie de la
dimension de B suivie des valeurs de B, il suffit donc dcrire :
2
1 >>> file = open('myfile.struct','wb')
2 >>> file.write(struct.pack('i',len(A)))
3 >>> A.tofile(file)
4 >>> file.write(struct.pack('i',len(B)))
5 >>> B.tofile(file)
6 >>> file.close()
1
Lendianness (ou le boutisme) est lordre dans lequel sont crit les octets. La racine du mot fait rfrence end
et non pas endian . Si les nombres sont crits de gauche droite, on parle de big-endian, (gros-boutisme) -
on commence par loctet de poids fort- sinon on parle de little-endian. Par extension, une date crite sous forme
AAAA/MM/JJ est big-endian. Lattribut sys.byteorder permet de connatre lendianness de votre processeur.
2
Le fichier myfile.struct gnr par cette suite dinstructions nest pas portable. Si lon change de machine, de
processeur, voire de compilateur, il ne sera pas possible de le relire en C++.
212 Chapitre 8. Python pour le calcul scientifique
Les instructions de lecture en C++ peuvent prendre la forme : TODO commenter
1 ifstream file("myfile.struct",ios ::binary|ios ::in|ios ::ate);
2 int size = (int) file.tellg();
3 file.seekg (0, ios ::beg);
4 int m;
5 file.read((char*)&m, sizeof(m));
6 int *a = new int[m];
7 for (int i = 0; i<m; i++)
8 file.read((char*)&a[i],sizeof(int));
9 file.read((char*)&m, sizeof(m));
10 nobytes = sizeof(double) ;
11 double *b = new double[m];
12 for (int i = 0; i<m; i++)
13 file.read((char*)&b[i],nobytes);
8.4.2. pyrex, cython. TODO: prendre le problme la base, voir sur http://docs.cython.
org/src/userguide/tutorial.html
pyrex est un langage analogue Python , utilis pour crer des modules en C pour Python.
cython
3
est un langage de programmation, surcouche de Python, proposant des extensions de
syntaxe semblable du C ou C++. Une de ces extensions permet la dclaration (optionnelle) de
types statiques. Par exemple en cython, on pourra trouver des dclarations comme :
1 cdef inline invSquareInline(int i) :
2 return 1./i**2
Le mot cl cdef remplace dans ce cas linstruction (Python) def. Pour les programmeurs C,
linstruction inline na pas de secret. Le paramtre i de la fonction est explicitement dclar
entier, comme en C/C++.
cython est bas sur pyrex, proposant (selon la documentation) quelques fonctionalits et optimi-
sations davant garde supplmentaires.
cython est actuellement la version 0.12.1 et nest pas exploitable de manire totalement opra-
tionnelle. Cest cependant un outil prometteur, en conjonction avec NumPy et SciPy, pour acc-
lrer radicalement lexcution des programmes Python .
Dans un programme cython, le fichier source est traduit en code C/C++ optimis, puis compil
comme une extension module Python.
3
Le dveloppement de cython est financ par google et enthougt. Voir http://cython.org/.
8.4 C/C++ en Python 213
Cette approche permet une excution trs rapide des programmes et une bonne intgration avec
les librairies externes C, tout en conservant la productivit du programmeur, typique de Python.
Ce qui suit, adapt du tutorial cython
4
, permet de tester une installation de cython, et den me-
surer lapport en terme de performance par rapport un programme Python conventionnel. On
considre le script Python suivant qui calcule 100 fois et retourne une valeur approche de bas
sur la formule
2
= 6
k+
1
k
2
Prliminaires : profilage dun script Python . Le script Python est stock dans le fichier
pi1.pyx. Son nom (.pyx) indique quil sagit dun script cython, mais dans un premier temps il
ne contient que des instructions en pur Python .
1 #fichier pi.pyx
2 @cython.profile(False)
3 def pynvSquare(i) :
4 return 1./i**2
5 def pypi(n=65535) :
6 for w in range(100) :
7 val = 0.0
8 for k in range(1,n+1) :
9 val += pynvSquare(k)
10 return (6 * val)**.5
Ligne 3 : en terme de performances, on pourrait bien videmment se dispenser de la fonction
pyinvSquare() mais la performance du programme nest pas ici lobjectif vis. La srie est
somme jusqu n = 65535 seulement, car au del, le compilateur C donne la valeur n = 0 ce
qui produit une exception ZeroDivisionError.
Ligne 2 : un dcorateur pour demander au profiler cython de ne pas dtailler les appels la
fonction pynvSquare(), mais seulement ceux de pypi(). Le profilage en dtail de la fonction
pynvSquare() gnre un surcot important qui risque de biaiser le rsultat.
Pour valuer les performances de ce script pi.pyx, on lappelle depuis un script de profiling
contenant ces lignes :
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 #fichier cython-profile.py
4 import pstats, cProfile
5 import pyximport
6 pyximport.install() #compilation auto de pi
7 import pi
4
http://docs.cython.org/src/tutorial/profiling_tutorial.html
214 Chapitre 8. Python pour le calcul scientifique
8 for p in ('pi.pypi()',) :
9 cProfile.runctx(p, globals(), locals(), "Profile.prof")
10 s = pstats.Stats("Profile.prof")
11 s.strip_dirs().sort_stats("time").print_stats()
Ligne 1 : indique que linterprteur est Python , cest lui qui va lancer cython.
Lignes 5-6 : permet la compilation automatique du module pi.pyx par cython. Plus gnralement,
les scripts .pyx imports seront compils par cython, les scripts pur python (.py) seront excuts
tel quels par Python .
Les lignes suivantes sont des instructions standard en Python destines profiler la fonction
pi.pypi() du module pi.
Ligne 7 : importation du module profiler.
Ligne 8 : pour le moment, seule la fonction pi.pypi() est profiler. Par la suite, nous ajouterons
diverses fonctions optimises dans le but de comparer les temps dexcution celui de lexemple
de base prsent ici.
Ligne 9 : demande au profiler dexcuter pi.pypi(), dans le contexte dfini par globals() et
locals(), et de stocker le rsultat dans Profile.prof.
Ligne 10-11 : le module pstats est utilis pour extraire du fichier Profile.prof les statitistiques
qui nous intressent. La mthode strip_dirs() supprime les chemins absolus de la sortie, pour
ne garder que les noms de fichier. Les mthodes sort_stats() et print_stats() ont des noms
suffisament vocateurs pour quil soit inutile de les commenter.
On lance le script de profilage :
$ ./cython-test0.py
et on obtient le rsultat :
Mon Apr 18 06 :58 :01 2011 Profile.prof
4 function calls in 4.256 CPU seconds
Ordered by : internal time
ncalls tottime percall cumtime percall filename :line-
no(function)
1 4.256 4.256 4.256 4.256 cypi0.pyx :9(pypi0)
1 0.000 0.000 4.256 4.256 <string> :1(<module>)
1 0.000 0.000 4.256 4.256 {cypi0.pypi0}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_ls-
prof.Profiler' objects}
Nous nous attachons au seul rsultat final, cest dire au temps dexcution total, ici 4.256 se-
condes de CPU
8.4 C/C++ en Python 215
cython au travail. Modifions maintenant le script pi.pyx en y introduisant une version sup-
plmentaire du calcul de en cython :
1 cimport cython
2 @cython.profile(False)
3 def invSquare(int i) :
4 return 1./i**2
5 def pi0(int n=65535) :
6 cdef double val = 0.
7 cdef int k
8 for w in range(100) :
9 val = 0.0
10 for k in range(1,n+1) :
11 val += invSquare(k)
12 return (6 * val)**.5
Ligne 1 : importation la cc .
Ligne 3 et 5 : cython est averti que les paramtres i et n sont entiers, information qui sera prise
en compte par cython pour produire un code C optimis.
Lignes 6-7 : de mme pour les variables val (relle double prcision) et k (entier).
Le reste est inchang.
On demande ensuite au script de profiling dexcuter les deux versions pypi et pi0 de la fonction
qui calcule . Ce qui se fait en changeant la ligne 8 fichier pi.pyx en :
1 for p in ('pi.pypi()','pi.pi0()') :
2 etc...
Lexcution du cython-profile.py fournit le rsultat :
4 function calls in 4.480 CPU seconds => pypi()
4 function calls in 0.786 CPU seconds => pi0()
qui montre quune utilisation lmentaire de cython divise dj le temps dexcution par 5, 67
La dernire amlioration suggre est de dclarer inline la fonction invSquare(int i), en
utilisant la dfinition :
1 @cython.profile(False)
2 cdef inline invSquareInline(int i) :
3 return 1./i**2
4 def pi1(int n=65535) :
5 cdef double val = 0.
6 cdef int k
7 for w in range(100) :
216 Chapitre 8. Python pour le calcul scientifique
8 val = 0.0
9 for k in range(1,n+1) :
10 val += invSquareInline(k)
11 return (6 * val)**.5
Ligne 2 : la dfinition dune fonction inline en cython se fait par cdef, au lieu de def en pur
Python.
Cette fois-ci le gain en performance est rellement tonnant !
4 function calls in 4.480 CPU seconds => pypi()
4 function calls in 0.786 CPU seconds => pi0()
4 function calls in 0.100 CPU seconds => pi1()
Au total, sur cet exemple simple, cython permis de diviser par 45 le temps dexcution.
8.4.3. ctypes, swig.
8.4.4. boost.
8.4.5. shiboken TODO. Shiboken est un plugin de GeneratorRunner qui gnre du code
C++pour des extensions CPython. La premire gnration de PySide tait base sur les templates
de Boost.
Pour utiliser Shiboken, il faut avoir install les paquetages apiextractor, generatorrunner,
pyside et shiboken avec les versions de dveloppement.
Lutilisation de Shiboken est plutt complexe, le tutoriel http://developer.qt.nokia.com/
wiki/PySide_Binding_Generation_Tutorial est un bon point dentre.
Pour rsumer le contenu de ce tutoriel, les tapes ncessaires la cration et au test du module
foo, partir des codes sources fournis sont les suivantes :
(1) compiler la bibliothque C++
1 $ cd libfoo
2 $ qmake
3 $ make
(2) gnrer, compiler et tester le binding : (cette tape est assez fastidieuse dcortiquer !)
1 $ cd foobinding-cmake
2 $ mkdir build
3 $ cd build
4 $ cmake ..
5 $ make
6 $ make test
8.5 Visualisation de donnes 217
8.4.6. weave.
8.5. Visualisation de donnes
8.5.1. matplotlib, pylab. http://matplotlib.sourceforge.net/users/pyplot_tutorial.
html
matplotlib et pylab sont deux module trs semblables pour les reprsentations graphiques (2d).
matplotlib est orient objet, tandis que pylab est procdural. Les deux proposent une interface
la Matlab.
La galerie sur le site http://matplotlib.sourceforge.net est une fonctionalit trs simple
pour aborder matplotlib. Il suffit de cliquer sur lune des multiples figures proposes pour obtenir
le code correspondant. Extrmement efficace.
Il peut arriver que matplotlib se plaigne de ne pas possder le backend requis et refuse daf-
ficher le graphique. Un backend est un processus qui gre les oprations graphiques en arrire
plan.
Pour connatre la liste des backend reconnus (la documentation matplotlib ne semble pas jour),
on peut excuter le code suivant dans une session Python :
1 >>> import matplotlib
2 >>> matplotlib.use('toto')
3 [...]
4 ValueError : Unrecognized backend string "toto" : valid strings
are ['ps', 'Qt4Agg', 'GTK', 'GTKAgg', 'svg', 'agg', 'cairo', '
MacOSX', 'GTKCairo', 'WXAgg', 'TkAgg', 'QtAgg', 'FltkAgg', 'pdf
', 'CocoaAgg', 'emf', 'gdk', 'template', 'WX']
Le plus sr est dutiliser le backend tkAgg ou agg.
8.5.2. SciTools, EasyViz. http://code.google.com/p/scitools/SciTools
https://scitools.googlecode.com/hg/doc/easyviz/easyviz_sphinx_html/index.html
il sagit dun package proposant une interface Pythonunifie pour divers packages de visualisa-
tion comme Matplotlib, Gnuplot, etc..
Les exemples du tutorial ne fonctionnent pas trs bien.
8.5.3. Vtk. http://www.vtk.org/Wiki/VTK/Examples/Python/Widgets/ContourWidget
218 Chapitre 8. Python pour le calcul scientifique
8.5.4. Mayavi. Attention, dmarrer avec
$ ipython -wtrhead
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/mlab.
html
8.5.5. Paraview. http://www.itk.org/Wiki/ParaView/Python_Scripting
Exercices
Exercice 80. Exercice
Exercice 81. Optimisation. Soit
F (x, y, z) =
x
2
13
4
x
y
4
z
4
+
3
2
y
2
x
2
+ y
z
2
1
2
z
3
+ 6z
2
+
51
4
z
x
4
+
y
4
+ 10
= (x
, y
, z
, y
, z
) = (0, 0, 0) F (x
, y
, z
)
2
2
= 0
(x
, y
, z
)
2
2
au voisinage de (x
, y
).
Exercice 82. Rsolution dune quation diffrentielle
Rsoudre sur [0, 1] lquation diffrentielle y
2 (3 + 2t
3
) y = 0 avec les conditions initiales
y (0) = 0 et y
(0) = 1
Mettre tout dabord lquation sous la forme Y = F (Y, t) avec des conditions initiales Y (0) =
Y
0
Utiliser la fonction scipy.integrate.odeint()
Tracer la solution, comparer graphiquement avec la solution exacte y (t) = te
t
2
Calculer le gradient en Y de la fonction F et lutiliser dans la rsolution. Comparer les temps
dexcution pour obtenir une prcision donne
5
Il ny a pas unicit de la solution. Une solution possible est
(
3
2
,
1
2
, 2
)
8.5 Exercices 219
Exercice 83. Rsoudre lquation diffrentielle :
y
ty = 0, t [0, 1]
avec les conditions initiales
y (0) =
1
3
2
3
(
2
3
)
y
(0) =
1
3
1
3
(
1
3
)
Tracer la fonction t y (t)
Exercice 84. Indexation multiple et performances.
Comparer en temps dexcution les deux modes dindexation multiple par tableau ou par liste :
1 A = arange(10)
2 il = [1, 2, 3]
3 ia = array([1, 2, 3])
4 A[il]
5 A[ia]
Exercice 85. cython
Considrons le code Python (fichier integral.pyx) :
1
2 def f(x) :
3 return x**2-x
4
5 def integrate_f(a, b, N) :
6 s = 0
7 dx = (b-a)/N
8 for i in range(N) :
9 s += f(a+i*dx)
10 return s * dx
(1) Mettre en place un script Python , intprof.py pour profiler le code. (Voir 8.4.2 page 213)
(2) Dupliquer le code pour dfinir f1() et integrate_f1(). Utiliser cython pour leur ajouter
des dclarations de type de variables et paramtres, et profiler le code obtenu.
(3) Ajouter une troisime version de f et integrate_f, dans laquelle la fonction f est type par
la dclaration cdef double f2(double x). Comparer.
220 Chapitre 8. Python pour le calcul scientifique
Exercice 86. Intgration, vectorisation.
Programmer la formule dintgration approche (trapzes compose)
b
a
f (x) dx h
(
1
2
f (a) +
1
2
f (b) +
1k<n
f (a + ih)
)
avec h =
ba
n
(1) avec une boucle classique ;
(2) en utilisant une vectorisation de la fonction f ;
(3) Tracer laide de Matplotlib, les deux courbes des temps dexcution en fonction de n.
on utilisera les fonctions f (x) = 1 + x et g (x) = e
x
2
ln (x + x sin x)
Exercice 87. Ecrire une fonction axpy(a,X,Y) calcule aX + Y pour X, Y R
n
et a R
laide dune boucle
crire une fonction analogue vaxpy(a,X,Y) en utilisant la vectorisation dans NumPy.
Comparer les temps dexcution.
Exercice 88. Traitement dimages : ajustement dune gaussienne. TODO
Solutions des exercices
Solution 80 Solution
Solution 81 (1) Le script Python :
8.5 Solutions des exercices 221
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 from scipy import array, zeros, meshgrid, optimize, r_
4 import matplotlib
5 matplotlib.use('TkAgg') #pour MacOSX
6 from pylab import figure, show
7 from mpl_toolkits.mplot3d import Axes3D
8 from matplotlib import cm
9
10 def F(xx) :
11 x, y, z = xx[0],xx[1],xx[2]
12 X = x*x -13*x/4.-y/4.-z/4.+3/2.
13 Y = y*y-x/2.+y-z/2.-1/2.
14 Z = z*z*z+6.*z*z+51*z/4.-x/4.+y/4.+10.
15 return X*X+Y*Y+Z*Z
16
17 def plot(F, X0, dX, r, z0) :
18 x0,y0 = X0[0], X0[1]
19 dx,dy = dX[0], dX[1]
20 x = r_[x0-dx :x0+dx :r*1j]
21 y = r_[y0-dy :y0+dy :r*1j]
22 x, y = meshgrid(x, y)
23 # ou bien en une ligne :
24 # x, y = mgrid[x0-dx :x0+dx :r*1j, y0-dy :y0+dy :r*1j]
25 z = F([x, y, z0])
26 fig = figure()
27 ax = Axes3D(fig)
28 ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.jet)
29 show()
30 if __name__=="__main__" :
31 A = optimize.fmin_cg(F, zeros(3))
32 print A
33 X0, z0 = (A[0], A[1]), A[2]
34 plot(F, X0, (1.,1.), 30, z0)
(2) Le trac de la fonction (x, y) = F (x, y, 2)
2
2
au voisinage de (x
, y
) =
(
3
2
,
1
2
)
222 Chapitre 8. Python pour le calcul scientifique
Solution 82 Rsolution dune quation diffrentielle
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import scipy as sp
4 from scipy.integrate import odeint
5 from scipy import array, r_
6
7 def F(Y,t) :
8 return array([2*(3+2*t*t*t)*Y[1],Y[0]])
9 def trace(N,T, s=None) :
10 import matplotlib
11 matplotlib.use('tkAgg')#pas obligatoire
12 from matplotlib import pyplot
13 fig = pyplot.figure()
14 pyplot.plot(N, T, '+r',N , s, '*b' )
15 pyplot.grid(True)
16 pyplot.show()
17
18 def solex(t) :
19 return t*sp.exp(t*t)
20
21 if __name__=="__main__" :
22 Y0 = array([1,0])
23 T = r_[0 :1 :100j]
24 Y = odeint(F,Y0,T)
8.5 Solutions des exercices 223
25 y = Y[ :,1]
26 s = solex(T)
27 trace(T,y,s)
Le trac de la solution exacte et de la solution numrique :
Solution 83 quation diffrentielle
Solution 84
1 #/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import cProfile
4 from numpy import arange
5 def tests(A,i,n=10000000) :
6 for k in range(n) : A[i]
7 A = arange(10000)
8 il = [1, 2, 3]
9 ia = array([1, 2, 3])
10 cProfile.run('tests(A,il)')
11 cProfile.run('tests(A,ia)')
et le rsultat rsum :
4 function calls in 94.579 CPU seconds
4 function calls in 12.602 CPU seconds
224 Chapitre 8. Python pour le calcul scientifique
Lindexation par array est 7,5 fois plus rapide que lindexation par liste.
Solution 85 (1) Le profiler :
1 #/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import pstats, cProfile
4 import pyximport
5 pyximport.install() #compilation auto de integral
6 import integral
7 pfile = 'integral.prof'
8 cProfile.run('integral.integrate_f0(0.0, 1.0, 1000000)', pfile)
9 s = pstats.Stats(pfile)
10 s.strip_dirs().sort_stats("time").print_stats()
(2) Le typage des variables et paramtres :
1 # -*- coding : utf-8 -*-
2 # cython : profile=True
3 # <ici le code Python pur>
4 #Typage variables et paramtres
5 def f1(double x) :
6 return x**2-x
7 def integrate_f1(double a, double b, int N) :
8 cdef int i
9 cdef double s, dx
10 s = 0
11 dx = (b-a)/N
12 for i in range(N) :
13 s += f1(a+i*dx)
14 return s * dx
(3) Le typage de la fonction
1 cdef double f2(double x) :
2 return x**2-x
Solution 86 Les fonctions test intgrer
1 def f(x) : return 1+x
2 def g(x) : return exp(-x*x)*log(x+sin(x))
Intgration (mthode des Trapzes compose), boucle simple :
8.5 Solutions des exercices 225
1 def integ(f, a, b, n=100) :
2 h = float(b-a)/n
3 I = (f(a)+f(b))*0.5
4 for i in range(1,n) :
5 I += f(a+i*h)
6 return I*h
Intgration, fonction f vectorise :
1 def v_integ(f, a, b, n=100) :
2 f = sp.vectorize(f)
3 h = float(b-a)/n
4 x = sp.linspace(a, b, n+1)
5 I = h*(sp.sum(f(x))-0.5*(f(a)+f(b)))
6 return I
Le calcul des temps dxcution en fonction du nombre de points :
1 def temps(f, a=0, b=1, N=(100,10001,100)) :
2 import time
3 first, last, step = N
4 nbint = sp.arange(first, last, step)
5 times = sp.empty(len(nbint))
6 for k, n in enumerate(nbint) :
7 t = time.time()
8 integ(f,a,b,n)
9 times[k] = (time.time()-t)
10 return nbint, times
Le trac des rsultats :
1 def trace(N,T) :
2 """Tracs"""
3 import matplotlib
4 matplotlib.use('tkAgg')
5 from matplotlib import pyplot
6 fig = pyplot.figure()
7 pyplot.plot(N, T, 'r')
8 pyplot.grid(True)
9 pyplot.show()
226 Chapitre 8. Python pour le calcul scientifique
Solution 87
1 def axpy(a,X,Y) :
2 Z = zeros(len(X))
3 for i in range(len(X)) :
4 Z[i] = a*X[i]+Y[i]
5 return Z
6
7 def vaxpy(a,X,Y) :
8 return a*X+Y
9
10 if __name__=="__main__" :
11 import cProfile
12 from scipy import random
13 X = random.random(100000)
14 Y = random.random(100000)
15 a = 2.0
16 cProfile.run ("axpy(a,X,Y)")
17 cProfile.run ("vaxpy(a,X,Y)")
lexcution on obtient :
7 function calls in 0.198 CPU seconds
3 function calls in 0.001 CPU seconds
La version vectorise est 200 fois plus rapide.
Solution 88 Traitement dimages : ajustement dune gaussienne
1 #!/usr/bin/python
2 # -*- coding : utf-8 -*-
3 import sys
4 import scipy as sp
5 from scipy import array, r_, where, exp, optimize, meshgrid
6 import matplotlib
7 matplotlib.use('TkAgg') #pour MacOSX
8 from pylab import figure, show
9 from mpl_toolkits.mplot3d import Axes3D
10 from matplotlib import cm
11
12 def readImage(filename) :
13 try : file = open(filename)
14 except IOError :
15 print "Impossible d'ouvrir le fichier %s"%filename
8.5 Solutions des exercices 227
16 exit()
17 P = sp.loadtxt(filename, skiprows = 8)
18 return P
19
20 def support(pixels, i0, j0, n) :
21 return pixels[i0-n :i0+n+1,j0-n :j0+n+1]
22
23 def adjustGauss(pixels, i0, j0, n) :
24 supp = support(pixels, i0, j0, n)
25 sig0 = (pixels[i0,j0], n, n, 3.0, 0.0)
26 sig = optimize.fmin(phi, sig0, args=(supp,), full_output=0)
27 return sig
28
29 def gaussienne(X, sig) :
30 x,y = X[0],X[1]
31 g0, x0, y0, w, b = sig
32 return b + g0*exp(-(x-x0)**2/(2*w**2))*exp(-(y-y0)**2/(2*w**2))
33
34 def phi(sig, ph) :
35 g0, x0, y0, w, b = sig
36 s = 0
37 m,n = ph.shape
38 for i in range(m) :
39 for j in range(n) :
40 s += (ph[i,j]-gaussienne([i,j], sig))**2
41 return s
42
43 def plot(pixels, sig, i0, j0, n, r) :
44 g0, x0, y0, w, b = sig
45 fig = figure()
46 ax = Axes3D(fig)
47 x = r_[x0-n :x0+n :r*1j]
48 y = r_[y0-n :y0+n :r*1j]
49 x, y = meshgrid(x, y)
50 z = gaussienne([x,y], sig)
51 ax.plot_surface(i0-n+x, j0-n+y, z, rstride=1, cstride=1)#, cmap
=cm.jet)
52
53 supp = support(pixels, i0, j0, n)
54 xdata = r_[i0-n :i0+n :(2*n+1)*1j]
55 ydata = r_[j0-n :j0+n :(2*n+1)*1j]
56
228 Chapitre 8. Python pour le calcul scientifique
57 xdata,ydata = meshgrid(xdata, ydata)
58 # ax.plot_surface(xdata, ydata, supp, rstride=1, cstride=1, cmap=
cm.jet)
59 # ax.plot_wireframe(xdata, ydata, supp)
60 for i in range(len(xdata)) :
61 ax.scatter(xdata[i, :], ydata[i, :], supp[i, :], c='r')
62 show()
63
64 if __name__=="__main__" :
65 try : filename = sys.argv[1]
66 except IndexError :
67 filename = 'srv_9.dat'
68 pixels = readImage(filename)
69
70 i0,j0 = sp.where(pixels == pixels.max())
71 n = 3
72
73 sig = adjustGauss(pixels, i0, j0, n)
74 r = 10
75 plot(pixels, sig, i0, j0, n, r)
Index
A
affectation multiple, 33, 59
alias, 87, 125
and, 62
argument, 119
ASCII, 91
attribut, 130, 154
B
bibliothque standard, 128, 177
break, 59
buffering, 136
builtins, 130
bytecode, 128
C
cahier des charges, 153
camel case, 16
caractre, 37
chane de caractre, 36, 92
chane de documentation, 118
chemin, 178
complex, 81
concatnation, 37
constructeur, 154
continue, 59
convention de nommage, 15
conventions de programmation, 16
coupure du plan complexe, 189
court-circuit, 62
csv, 191
cython, 212
D
dballage, 86
darguments, 121
de tuple, 121
dcoupage, 87
data attribute, 155
descripteur de format, 99
dict
items(), 66
keys(), 66
values(), 66
dictionnaire, 41
dir(), 30
division entire, 35
divmod(), 35
docstring, 36, 118
doctest, 45
donne, 155
dynamique, 13
dynamiquement typ, 13
E
effet de bord, 119
elif, 60
else, 59, 60
else (try-), 101
emballage, 86
empilage de tableaux, 204
ensembles, 99
Entre-sortie, 42
enumerate(), 66
espace de noms, 123
except, 101
exception, 101
expression gnratrice, 85
expression rgulire, 191
F
False, 62
fichier module, 16
FIFO, 89
files dattente, 89
filter(), 68
finally, 101
230 Chapitre 8. Index
float, 81
fonction-mthode, 156
fonctions intgres, 130
abs(), 137
all(), 132
any(), 132
assert(), 137
callable(), 132
chr(), 131
compile(), 132
delattr(), 130
dir(), 30, 137
divmod(), 35, 137
enumerate(), 66, 134
eval(), 132
exec(), 133
filter(), 68, 134
getattr(), 130
globals(), 133
hasattr(), 130
hash(), 137
help(), 30
hex(), 131
id(), 79, 137
input(), 50, 135
isinstance(), 137
issubclass(), 137
len(), 137
map(), 67, 134
max(), 134
min(), 135
next(), 135
oct(), 131
open(), 42, 135
ord(), 131
pow(), 137
quit(), 137
range(), 50, 65, 135
raw_input(), 135
reduce(), 71
reload(), 126
repr(), 98
reversed(), 67, 135
round(), 137
setattr(), 130
sorted(), 67, 135
str(), 98
type(), 32, 137
zip(), 66, 135
for, 61
from, 125
G
gnrateur, 82, 84
garbage collector, 13
getter, 162
H
hritage, 157
help(), 30
historique, 12
I
if, 60
immuable, 79
immutable, 79
import, 125
in, 62
indent, 59
indentation, 59
index, 100
input(), 50
instance, 153, 155
instantiation de classe, 155
instructions
affectation, 80
break, 59
continue, 59
def, 44
del, 41, 90
else, 59
else(try-), 101
except, 101
finally, 101
for, 61
from, 125
if, 60
import, 125
is, 40
pass, 59
return, 44
try, 101
while, 59
int, 81
inter-oprable, 13
introspectif, 13
is, 40, 62
is not, 62
ISO 8859, 91
itrable, 61, 82
231
itrateur, 61, 82, 83
inverse, 135
J
jocker, 181
Jython, 14
L
lambda, 122
LGI, 124
LIFO, 89
ligne de commande, 16
List comprehension, 68
liste, 88
Listes en comprehension, 68
locals(), 133
logiciel libre, 13
M
mmoire tampon, 136
mthode, 155
spciale, 154
virtuelle, 13, 159
map(), 67
method, 155
MIME, 191
modifiables, 79
module, 125
fichier, 16
standard, 128
modules
cProfile, 185
doctest, 45
math, 33
os, 177
pickle, 42, 43, 51
profile, 185
pstats, 185
string, 95
timeit, 184
unittest, 187
mots rservs, 79
multi-thread, 13
mutable, 79
N
name space, 123
nombre parfait, 50
nombres de Fibonacci, 118
nombres parfaits, 50
non modifiables, 79
Numpy, 197
O
objet, 31
classe, 155
instances, 155
mthodes, 155
oprateur crochet, 37
oprations, 35
or, 62
orthogonal, 13
P
packing, 86
paquetages, 127
pass, 59
passage darguments
par affectation, 119
par rfrence, 119
par valeur, 119
path, 178
persistance, 44
pickle, 43, 51
pile, 89
plan Unicode, 90
point de code, 90
pointeurs, 13
porte, 124
globale, 124
interne, 124
locale, 124
profilage, 128, 143
profiling, 128
programmation dirige par la documentation, 46
Programmation Oriente Objets, 45
prompt, 16
properties, 162
Python Software Foundation, 13
R
rfrences, 155
rflectif, 13
rutilisabilit, 45
range(), 50, 65
rgle LGI, 124
reduce(), 71
regular expression, 191
reverse iterator, 135
reversed(), 67
richesse lexicale, 106
232 Chapitre 8. Index
S
squence, 85
scope, 124
scripts Python , 16
setter, 162
slices, 38
slicing
squences, 87
tableaux, 201
sorted(), 67
str, 36
surcharge, 13
T
table de symboles, 118
tabulations, 16
timeit, 184
tranches, 38
True, 62
try, 101
tuple, 85
unpacking, 121
type(), 32
types
complex, 81
dict, 41, 100
float, 81
frozenset, 99
int, 81
list, 39, 85, 88
set, 99
str, 36
str, bytes, bytearray, 90
tuple, 85
U
Unicode, 90
unittest, 187
unpacking, 86
utf-8, 91
V
valeur dindentation, 16
variable, 79
variables, 32
variables prives, 13
vue, 101
W
while, 59
X
xml.dom, 191
xml.sax, 191
Z
zip(), 66
Bibliographie
[LA] Mark Lutz, David Ascher, Introduction Python, ed OReilly, Janvier 2000, ISBN 2-84177-089-3
[ML] Mark Lutz, Programming Python, Troisime Edition, ed OReilly & Associates, Aot 2006, ISBN
0596009259 10
[HPL] Hans Petter Langtangen, Python Scripting for Computational Science. Simula Research La-
boratory and Department of Informatics University of Oslo. /home/puiseux/enseignement/
CoursOutilsInformatiques/Python_scripting_for_computational_science.04.pdf
[MP] Mark Pilgrim, dive into Python (Plongez au coeur de Python) http://diveintopython.org/,
traduction franaise : Xavier Defrang, Jean-Pierre Gay, Alexandre Drahon./home/puiseux/doc/
python/frdiveintopython.pdf
[VR] Guido van Rossum, Tutoriel Python, Release 2.0.1. /home/puiseux/doc/python/tut-fr.pdf
[GS-1] Grard Swinnen, Apprendre programmer avec Python, http://inforef.be/swi/download/
apprendre_python.pdf
[GS-2] Grard Swinnen, Apprendre programmer avec Python 3, d. Eyrolles, 2010, ISBN 978-2-212-
12708-9.
[EDM] Jeffrey Elkner, Allen B. Downey and Chris Meyers, http://openbookproject.net//thinkCSpy
[WK] http://fr.wikipedia.org/wiki/Python_(langage)
[PLR] Python Library Reference.http://docs.python.org/library/index.html
[TZ] Tarek Ziad,Python Petit guide lusage du dveloppeur agile, d. Dunos, collection tudes et dve-
loppements, 2007, ISBN 978-2-10-050883-9. 187
[MB] Matthieu Brucher, Python Les fondamentaux du langage, La programmation pour les scientifiques,
d. eni, Collection Ressources Informatique, Janvier 2008, ISBN 978-2-7460-4088-5.