2. La calculatrice Python▲
Comme tout langage, Python permet de manipuler des données grâce à un vocabulaire de mots réservés et grâce à des types de données — approximation des ensembles de définition utilisés en mathématique.
Ce chapitre présente les règles de construction des identificateurs, les types de données simples (les conteneurs seront examinés au chapitre 4Conteneurs standard) ainsi que les types chaîne de caractères.
Enfin, last but not least, ce chapitre s'étend sur les notions non triviales de variable, de référence d'objet et d'affectation.
2-1. Les modes d'exécution▲
2-1-1. Les deux modes d'exécution d'un code Python▲
2-2. Identificateurs et mots clés▲
2-2-1. Identificateurs▲
Comme tout langage, Python utilise des identificateurs pour nommer ses objets.
Un identificateur Python est une suite non vide de caractères, de longueur quelconque, formée d'un caractère de début et de zéro ou plusieurs caractères de continuation.
Sachant que :
- le caractère de début peut être n'importe quelle lettre Unicode (cf. Jeux de caractères et encodageJeux de caractères et encodage), y compris le caractère souligné (_) ;
- un caractère de continuation est un caractère de début ou un chiffre.
Les identificateurs sont sensibles à la casse et ne doivent pas être un mot réservé de Python 3 (voir le § « Les mots réservés de Python 3Les mots réservés de Python 3 » ci-dessous).
2-2-2. Style de nommage▲
Il est important d'utiliser une politique cohérente de nommage des identificateurs. Voici le style utilisé dans ce document(6) :
- nom_de_ma_variable pour les variables ;
- NOM_DE_MA_CONSTANTE pour les constantes ;
- maFonction, maMethode pour les fonctions et les méthodes ;
- MaClasse pour les classes ;
- UneExceptionError pour les exceptions ;
- nom_de_module pour les modules et pour tous les autres identificateurs.
Exemples :
NB_ITEMS =
12
# UPPER_CASE
class
MaClasse : pass
# TitleCase
def
maFonction
(
) : pass
# camelCase
mon_id =
5
# lower_case
Pour ne pas prêter à confusion, éviter d'utiliser les caractères l (minuscule), O et I (majuscules) seuls.
Enfin, on évitera d'utiliser les notations suivantes :
_xxx # usage interne
__xxx # attribut de classe
__xxx__ # nom spécial réservé
2-2-3. Les mots réservés de Python 3▲
La version 3.4 de Python compte 33 mots clés :
and |
del |
from |
None |
True |
as |
elif |
global |
nonlocal |
try |
assert |
else |
if |
not |
while |
break |
except |
import |
or |
with |
class |
False |
in |
pass |
yield |
continue |
finally |
is |
raise |
|
def |
for |
lambda |
return |
2-3. Notion d'expression▲
Une expression est une portion de code que l'interpréteur Python peut évaluer pour obtenir une valeur.
Les expressions peuvent être simples ou complexes. Elles sont formées d'une combinaison de littéraux représentant directement des valeurs, d'identificateurs et d'opérateurs.
>>>
id1 =
15.3
>>>
id2 =
id1 -
13
>>>
if
id2 >
0
:
... id3 =
7
... else
:
... id3 =
-
4
2-4. Les types de données entiers▲
Le type d'un objet Python détermine de quelle sorte d'objet il s'agit.
Python offre deux types entiers standard : int et bool.
2-4-1. Le type int▲
Le type int n'est limité en taille que par la mémoire de la machine(7).
Les entiers littéraux sont décimaux par défaut, mais on peut aussi utiliser les bases suivantes :
>>>
2013
# décimal (base 10)
2013
>>>
0
b11111011101 # binaire (base 2)
2013
>>>
0
o3735 # octal (base 8)
2013
>>>
0x7dd
# hexadecimal (base 16)
2013
2-4-1-a. Opérations arithmétiques▲
Les principales opérations :
>>>
20
+
3
23
>>>
20
-
3
17
>>>
20
*
3
60
>>>
20
**
3
8000
>>>
20
/
3
6.666666666666667
>>>
20
//
3
# division entière
6
>>>
20
%
3
# modulo (reste de la division entière)
2
>>>
abs(
3
-
20
) # valeur absolue
17
Bien remarquer le rôle des deux opérateurs de division :
2-4-1-b. Bases usuelles▲
Un entier écrit en base 10 (par exemple 179) peut être représenté en binaire, octal et hexadécimal en utilisant les syntaxes suivantes :
>>>
0
b10110011 # binaire
179
>>>
bin
(
179
)
'0b10110011'
>>>
0
o263 # octal
179
>>>
oct(
179
)
'0o263'
>>>
0xB3
# hexadécimal
179
>>>
hex(
179
)
'0xb3'
Les bases arithmétiques
En arithmétique, une base n désigne la valeur dont les puissances successives interviennent dans l'écriture des nombres, ces puissances définissant l'ordre de grandeur de chacune des positions occupées par les chiffres composant tout nombre.
Par exemple : kitxmlcodeinlinelatexdvp57_{n}= \left ( 5\times n^{1}\right )+\left (7\times n^{0} \right )finkitxmlcodeinlinelatexdvp
Certaines bases sont couramment employées :
- la base 2 (système binaire), en électronique numérique et informatique ;
- la base 8 (système octal), en informatique ;
- la base 16 (système hexadécimal), fréquente en informatique ;
- la base 60 (système sexagésimal), dans la mesure du temps et des angles.
Les changements de base
Un nombre dans une base kitxmlcodeinlinelatexdvpnfinkitxmlcodeinlinelatexdvp donnée s'écrit sous la forme d'addition des puissances successives de cette base.
Exemples :
kitxmlcodelatexdvp\begin{matrix} 57_{16}= \left ( 5\times 16^{1}\right )+\left (7\times 16^{0} \right )=87_{10} \\ 57_{8}= \left ( 5\times 8^{1}\right )+\left (7\times 8^{0} \right )=47_{10} \end{matrix}finkitxmlcodelatexdvp2-4-2. Le type bool▲
Principales caractéristiques du type bool(8) :
- deux valeurs possibles : False, True ;
- opérateurs de comparaison entre deux valeurs comparables, produisant un résultat de type bool : ==, !=, >, >=, < et <= :
>>>
2
>
8
False
>>>
2
<=
8
<
15
True
- opérateurs logiques : not, or et and ;
-
en observant les tables de vérité des opérateurs and et or, on remarque que :
cette optimisation est appelée « principe du shortcut » ou évaluation au « plus court » :- dès qu'un premier membre a la valeur False, l'expression False and expression2 vaudra False. On n'a donc pas besoin d'évaluer expression2,
- de même dès qu'un premier membre a la valeur True, l'expression True or expression2 vaudra True.
>>>
(
3
==
3
) or
(
9
>
24
)
True
>>>
(
9
>
24
) and
(
3
==
3
)
False
Les opérateurs booléens de base
En Python les valeurs des variables booléennes sont notées False et True. Les opérateurs sont notés respectivement not, and et or.
Pour être sûr d'avoir un résultat booléen avec une expression reposant sur des valeurs transtypées, appliquez bool() sur l'expression.
2-5. Les types de données flottants▲
La notion mathématique de réel est une notion idéale. Ce Graal est impossible à atteindre en informatique.On utilise une représentation interne (normalisée) permettant de déplacer la virgule grâce à une valeur d'exposant variable. On nommera ces nombres des flottants.
2-5-1. Le type float▲
- Un float est noté avec un point décimal (jamais avec une virgule) ou en notation exponentielle avec un « e » symbolisant le « 10 puissance » suivi des chiffres de l'exposant. Par exemple :
2.718
.02
-
1.6e-19
6.023e23
- Les flottants supportent les mêmes opérations que les entiers.
- Ils ont une précision finie limitée.
- L'import du module math autorise toutes les opérations mathématiques usuelles. Par exemple :
>>>
import
math
>>>
print
(
math.sin
(
math.pi/
4
))
0.7071067811865475
>>>>
print
(
math.degrees
(
math.pi))
180.0
>>>>
print
(
math.factorial
(
9
))
362880
>>>
print
(
math.log
(
1024
, 2
))
10.0
2-5-2. Le type complex▲
- Les complexes sont écrits en notation cartésienne formée de deux flottants.
- La partie imaginaire est suffixée par j :
>>>
print
(
1
j)
1
j
>>>
print
((
2
+
3
j) +
(
4
-
7
j))
(
6
-
4
j)
>>>
print
((
9
+
5
j).real)
9.0
>>>
print
((
9
+
5
j).imag)
5.0
>>>
print
((
abs(
3
+
4
j))) # module
5.0
- Un module mathématique spécifique (cmath) leur est réservé :
>>>
import
cmath
>>>
print
(
cmath.phase
(-
1
+
0
j))
3.141592653589793
>>>
print
(
cmath.polar
(
3
+
4
j))
(
5.0
, 0.9272952180016122
)
>>>
print
(
cmath.rect
(
1.
, cmath.pi/
4
))
(
0.7071067811865476
+
0.7071067811865475
j)
2-6. Variables et affectation▲
2-6-1. Les variables▲
Dès que l'on possède des types de données, on a besoin des variables pour stocker les données.
En réalité, Python n'offre pas directement la notion de variable, mais plutôt celle de référence d'objet. Tant que l'objet n'est pas modifiable (comme les entiers, les flottants, les chaînes, etc.), il n'y a pas de différence notable entre les deux notions. On verra que la situation change dans le cas des objets modifiables…
Une variable est un identificateur associé à une valeur. En Python, c'est une référence d'objet.
2-6-2. L'affectation▲
On affecte une variable par une valeur en utilisant le signe = (qui n'a rien à voir avec l'égalité en math !). Dans une affectation, le membre de gauche reçoit le membre de droite ce qui nécessite d'évaluer la valeur correspondant au membre de droite avant de l'affecter au membre de gauche.
import
math
a =
2
b =
7.2
*
math.log
(
math.e /
45.12
) -
2
*
math.pi
c =
b **
a
Pour ne pas confondre affectation et égalité, à l'oral, au lieu de dire « a égale 2 », dites « a reçoit 2 ».
La valeur d'une variable, comme son nom l'indique, peut évoluer au cours du temps. La valeur antérieure est perdue :
>>>
a =
3
*
7
>>>
a
21
>>>
b =
2
*
2
>>>
b
4
>>>
a =
b +
5
>>>
a
9
Le membre de droite d'une affectation étant évalué avant de réaliser l'affectation elle-même, la variable affectée peut se trouver en partie droite et c'est sa valeur avant l'affectation qui est utilisée dans le calcul :
>>>
a =
2
>>>
a =
a +
1
# incrémentation
>>>
a
3
>>>
a =
a -
1
# décrémentation
>>>
a
2
2-6-3. Affecter n'est pas comparer !▲
L'affectation a un effet (elle modifie l'état interne du programme en cours d'exécution), mais n'a pas de valeur (on ne peut pas l'utiliser dans une expression) :
>>>
c =
True
>>>
s =
(
c =
True
) and
True
File "<stdin>"
, line 1
s =
(
c =
True
) and
True
^
SyntaxError
: invalid syntax
La comparaison a une valeur (de type bool) utilisable dans une expression, mais n'a pas d'effet :
>>>
c =
"a"
>>>
s =
(
c ==
"a"
) and
True
>>>
s
True
2-6-4. Les variantes de l'affectation▲
Outre l'affectation simple, on peut aussi utiliser les formes suivantes :
>>>
v =
4
# affectation simple
>>>
v +=
2
# affectation augmentée. Idem à v = v + 2 si v est déjà référencé
>>>
v
6
>>>
c =
d =
8
# d reçoit 8 puis c reçoit d (c et d sont des alias)
>>>
c, d
(
8
, 8
)
>>>
e, f =
2.7
, 5.1
# affectation parallèle d'un tuple
>>>
(
e, f)
(
2.7
, 5.1
)
>>>
g, h =
['G'
, 'H'
] # affectation parallèle d'une liste
>>>
[g, h]
['G'
, 'H'
]
>>>
a =
3
>>>
a, b =
a +
2
, a *
2
# toutes les expressions sont évaluées avant la première affectation
>>>
a, b
(
5
, 6
)
2-6-5. Représentation graphique des affectations▲
Dans les schémas de la figure 2.2 les cercles représentent les identificateurs alors que les rectangles représentent les données.
Les affectations relient les identificateurs aux données : si une donnée en mémoire n'est plus reliée, le ramasse-miettes (garbage collector) de Python la supprime automatiquement (car son nombre de références tombe à zéro) :
2-7. Les chaînes de caractères▲
2-7-1. Présentation▲
Les chaînes de caractères : le type de données non modifiable str représente une séquence de caractères Unicode.
Non modifiable signifie qu'une donnée, une fois créée en mémoire, ne pourra plus être changée ; toute transformation résultera en la création d'une nouvelle valeur distincte.
Trois syntaxes de chaîne sont disponibles. Remarquez que l'on peut aussi utiliser le ' à la place de ", ce qui permet d'inclure une notation dans l'autre :
>>>
syntaxe1 =
"Première forme avec un retour à la ligne
\n
"
>>>
print
(
syntaxe1)
Première forme avec un retour à la ligne
>>>
syntaxe2 =
r"Deuxième forme. Chaîne brute\n sans retour à la ligne"
>>>
print
(
syntaxe2)
Deuxième forme. Chaîne brute\n sans retour à la ligne
>>>
syntaxe3 =
"""
Troisième forme
multiligne
très utile pour
la documentation
"""
>>>
print
(
syntaxe3)
Troisième forme
multiligne
très utile pour
la documentation
>>>
guillemets =
"L'eau vive"
>>>
guillemets
"L'eau vive"
>>>
apostrophes =
'Il a dit "gère !"'
>>>
apostrophes
'Il a dit "gère !"'
2-7-2. Opérations▲
- Longueur :
>>>
s =
"abcde"
>>>
len(
s)
5
>>>
s1 =
"abc"
>>>
s2 =
"defg"
>>>
s3 =
s1 +
s2
>>>
s3
'abcdefg'
>>>
s4 =
"Fi!"
>>>
s5 =
s4 *
3
>>>
s5
'Fi! Fi! Fi! '
2-7-3. Fonctions vs méthodes▲
On peut agir sur une chaîne en utilisant des fonctions (notion procédurale) communes à tous les types séquences ou conteneurs, ou bien des méthodes (notion objet) spécifiques aux chaînes.
- Exemple d'utilisation de la fonction len() :
>>>
lng =
len(
"abc"
)
>>>
lng
3
Exemple d'utilisation de la méthode upper(). Remarquez la différence de syntaxe : les méthodes utilisent la notation pointée :
>>>
"abracadabra"
.upper
(
)
"ABRACADABRA"
2-7-4. Méthodes de test de l'état d'une chaîne▲
Les méthodes suivantes sont à valeur booléenne, c'est-à-dire qu'elles retournent la valeur True ou False.
La notation entre crochets [xxx] indique un élément optionnel que l'on peut donc omettre lors de l'utilisation de la méthode.
La chaîne s =
"cHAise basSe"
nous servira de test pour toutes les méthodes de cette section.
- isupper() et islower() : retournent True si la chaîne ne contient respectivement que des majuscules/minuscules :
>>>
s.isupper
(
)
False
- istitle() : retourne True si seule la première lettre de chaque mot de la chaîne est en majuscule :
>>>
s.istitle
(
)
False
- isalnum(), isalpha(), isdigit() et isspace() : retournent True si la chaîne ne contient respectivement que des caractères alphanumériques, alphabétiques, numériques ou des espaces :
>>>
s.isalpha
(
)
True
>>>
s.isdigit
(
)
False
- startswith(prefix[, start[, stop]]) et endswith(suffix[, start[, stop]]) : testent si la sous-chaîne définie par start et stop commence respectivement par prefix ou finit par suffix :
>>>
s.startswith
(
'cH'
)
True
>>>
s.endswith
(
'aSSe'
)
False
2-7-5. Méthodes retournant une nouvelle chaîne▲
- lower(), upper(), capitalize() et swapcase() : retournent respectivement une chaîne en minuscules, en majuscules, en minuscules commençant par une majuscule, ou en casse inversée :
>>>
s.lower
(
)
chaise basse
>>>
s.upper
(
)
CHAISE BASSE
>>>
s.capitalize
(
)
Chaise basse
>>>
s.swapcase
(
)
ChaISE BASsE
- expandtabs([tabsize]) : remplace les tabulations par tabsize espaces (8 par défaut).
- center(width[, fillchar]), ljust(width[, fillchar]) et rjust(width[, fillchar]) : retournent respectivement une chaîne centrée, justifiée à gauche ou à droite, complétée par le caractère fillchar (ou par l'espace par défaut) :
>>>
s.center
(
20
, '-'
)
----
cHAise basSe----
>>>
s.rjust
(
20
, '@'
)
@@@@@@@@cHAise basSe
- zfill(width) : complète ch à gauche avec des 0 jusqu'à une longueur maximale de width :
>>>
s.zfill
(
20
)
00000000
cHAise basSe
- strip([chars]), lstrip([chars]) et rstrip([chars]) : suppriment toutes les combinaisons de chars (ou l'espace par défaut) respectivement au début et en fin, au début, ou en fin d'une chaîne :
>>>
s.strip
(
'ce'
)
HAise basS
- find(sub[, start[, stop]]) : renvoie l'index de la chaîne sub dans la sous-chaîne start à stop, sinon renvoie -1. rfind() effectue le même travail en commençant par la fin. index() et rindex() font de même, mais produisent une erreur (exception) si la chaîne n'est pas trouvée :
>>>
s.find
(
'se b'
)
4
- replace(old, new[, count]) : remplace count instances (toutes par défaut) de old par new :
>>>
s.replace
(
'HA'
, 'ha'
)
chaise basSe
- split(seps[, maxsplit]) : découpe la chaîne en maxsplit morceaux (tous par défaut). rsplit() effectue la même chose en commençant par la fin et striplines() effectue ce travail avec les caractères de fin de ligne :
>>>
s.split
(
)
['cHAise'
, 'basSe'
]
- join(seq) : concatène les chaînes du conteneur seq en intercalant entre chaque élément la chaîne sur laquelle la méthode est appliquée :
>>>
"**"
.join
(
['cHAise'
, 'basSe'
])
cHAise**
basSe
2-7-6. Indexation simple▲
Pour indexer une chaîne, on utilise l'opérateur [] dans lequel l'index, un entier signé qui commence à 0 indique la position d'un caractère :
>>>
s =
"Rayon X"
# len(s) ==> 7
>>>
s[0
]
'R'
>>>
s[2
]
'y'
>>>
s[-
1
]
'X'
>>>
s[-
3
]
'n'
2-7-7. Extraction de sous-chaînes▲
Extraction de sous-chaînes. L'opérateur [ ] avec 2 ou 3 index séparés par le caractère : permet d'extraire des sous-chaînes (ou tranches) d'une chaîne.
Par exemple :
>>>
s =
"Rayon X"
# len(s) ==> 7
>>>
s[1
:4
] # de l'index 1 compris à 4 non compris
'ayo'
>>>
s[-
2
:] # de l'index -2 compris à la fin
' X'
>>>
s[:3
] # du début à l'index 3 non compris
'Ray'
>>>
s[3
:] # de l'index 3 compris à la fin
'on X'
>>>
s[::2
] # du début à la fin, de 2 en 2
'RynX'
>>>
s[::-
1
] # de la fin au début (retournement)
'X noyaR'
2-8. Les données binaires▲
2-8-1. Les types binaires▲
Python 3 propose deux types de données binaires : bytes (non modifiable) et bytearray (modifiable).
>>>
mot =
"Animal"
>>>
type(
mot)
<
class
'str'
>
>>>
>>>
b_mot =
b"Animal"
>>>
type(
b_mot)
<
class
'bytes'
>
>>>
>>>
bmot =
bytearray
(
b_mot)
>>>
type(
bmot)
<
class
'bytearray'
>
Une donnée binaire contient une suite de zéro ou plusieurs octets, c'est-à-dire d'entiers non signés sur 8 bits (compris dans l'intervalle [0…255]). Ces types « à la C » sont bien adaptés pour stocker de grandes quantités de données. De plus Python fournit des moyens de manipulation efficaces de ces types.
Les deux types sont assez semblables au type str et possèdent la plupart de ses méthodes. Le type modifiable bytearray possède des méthodes communes au type list.
2-9. Les entrées-sorties▲
L'utilisateur a besoin d'interagir avec le programme (Fig. 2.5). En mode « console » (on abordera les interfaces graphiques ultérieurement), on doit pouvoir saisir ou entrer des informations, ce qui est généralement fait depuis une lecture au clavier. Inversement, on doit pouvoir afficher ou sortir des informations, ce qui correspond généralement à une écriture sur l'écran.
2-9-1. Les entrées▲
Il s'agit de réaliser une saisie au clavier : la fonction standard input() interrompt le programme, affiche une éventuelle invite à l'écran et attend que l'utilisateur entre une donnée au clavier (affichée à l'écran) et la valide par .
La fonction input() effectue toujours une saisie en mode texte (la valeur retournée est une chaîne) dont on peut ensuite changer le type (on dit aussi transtyper ou cast en anglais) :
>>>
f1 =
input(
"Entrez un flottant :"
)
Entrez un flottant : 12.345
>>>
type(
f1)
<
class
'str'
>
>>>
f2 =
float(
input(
"Entrez un autre flottant :"
))
Entrez un autre flottant : 12.345
>>>
type(
f2)
<
class
'float'
>
On rappelle que Python est un langage dynamique (les variables peuvent changer de type au gré des affectations), mais également fortement typé (contrôle de la cohérence des types) :
>>>
i =
input(
"Entrez un entier :"
)
Entrez un entier : 3
>>>
i
'3'
>>>
iplus =
int(
input(
"Entrez un entier :"
)) +
1
Entrez un entier : 3
>>>
iplus
4
>>>
ibug =
input(
"Entrez un entier :"
) +
1
Entrez un entier : 3
Traceback (
most recent call last):
File "<stdin>"
, line 1
, in
<
module>
TypeError
: Can't convert '
int' object to str implicitly
2-9-2. Les sorties▲
En mode « calculatrice », Python lit-évalue-affiche (Fig. 2.1), mais la fonction print() reste indispensable aux affichages dans les scripts. Elle se charge d'afficher la représentation textuelle des informations qui lui sont données en paramètre, en plaçant un blanc séparateur entre deux informations, et en faisant un retour à la ligne à la fin de l'affichage (le séparateur et la fin de ligne peuvent être modifiés) :
>>>
a, b =
2
, 5
>>>
print
(
a, b)
2
5
>>>
print
(
"Somme :"
, a +
b)
Somme : 7
>>>>
print
(
a -
b, "est la différence"
)
-
3
est la différence
>>>
print
(
"Le produit de"
, a, "par"
, b, "vaut :"
, a *
b)
Le produit de 2
par 5
vaut : 10
>>>
print
(
"On a <"
, 2
**
32
, a*
b, "> cas !"
, sep=
"~~~"
)
On a <~~~
4294967296
~~~
10
~~~>
cas !
>>>
# pour afficher autre chose qu'un espace en fin de ligne :
>>>
print
(
a, end=
"@"
)
2
@>>>
print
(
)
>>>
2-9-3. Les séquences d'échappement▲
À l'intérieur d'une chaîne, le caractère antislash (\) permet de donner une signification spéciale à certaines séquences de caractères :
Séquence |
Signification |
---|---|
\saut_ligne |
saut de ligne ignoré (en fin de ligne) |
\\ |
affiche un antislash |
\' |
apostrophe |
\" |
guillemet |
\a |
sonnerie (bip) |
\b |
retour arrière |
\f |
saut de page |
\n |
saut de ligne |
\r |
retour en début de ligne |
\t |
tabulation horizontale |
\v |
tabulation verticale |
\N{nom} |
caractère sous forme de code Unicode nommé |
\uhhhh |
caractère sous forme de code Unicode 16 bits |
\Uhhhhhhhh |
caractère sous forme de code Unicode 32 bits |
\ooo |
caractère sous forme de code octal |
\xhh |
caractère sous forme de code hexadécimal |
>>>
print
(
"
\N
{pound sign}
\u00A3
\U000000A3
"
)
£ £ £
>>>
print
(
"d
\144
\x64
"
)
d d d
>>>
print
(
r"d \144 \x64"
) # la notation r"..." désactive la signification spéciale du caractère "\"
d \144
\x64