9. Les entrées-sorties (E/S) : formats#
Partie Programmation
Mis à jour : May 15, 2025, lecture : 7 minutes minimum, PhL.
Ce chapitre complète le chapitre “Entrées-sorties avec des fichiers”.
On y présente comment peaufiner le format ses entrées-sorties à l’écran ou dans des fichiers de texte.
9.1. Les formats d’écriture, de lecture et d’affichage#
Il s’agit de définir la façon dont s’écrivent, se lisent ou s’affichent à l’écran les informations textuelles, i.e. les chaînes de caractères.
Exemple : combien de chiffres après la virgule d’un float
, utiliser une notation scientifique (\(\pm 1.xxxx \cdot 10^E\)), insérer ou non des caractères avant la str
à afficher, …
On commence par la syntaxe qui permet d’exprimer le formatage voulu (syntaxe un peu lourde au début), puis on montre deux moyens d’appliquer l’opération de formatage : les chaînes formatées (ou f-string en python) puis la méthode plus générale .format
(méthode définie pour les str
).
Ces formats d’affichage s’appliquent aux chaînes de caractères utiles aux entrées-sorties textuelles (avec print()
pour l’écran, mais aussi write()
et read()
pour les fichiers de texte).
9.1.1. Spécifier le format de nombres et des chaînes de caractères#
La syntaxe générale d’un format (d’écriture ou d’affichage) est :
:[drapeau][largeur][.precision][type]
Après le symbole :
, chacun des 4 champs est optionnel.
[drapeau]
contrôle la justification de la valeur par :un caractère de remplissage (optionnel) :
.
,*
,-
, …et sa position : centré :
^
, aligné à gauche :<
, à droite :>
[largeur]
: la largeur de l’écriture (en nombre de caractères)[.precision]
: le nombre de chiffres après la virgule.
pour les nombres flottants[type]
: le paramètre le plus important qui dépend du type de la valeur et décrit un mode général de représentation.
Une valeur de format est aussi appelée code de format par la littérature python.
Rmq. importante Les exemples qui suivent pour illustrer l’effet de ces codes sont donnés :
sur l’affichage à l’écran par
print()
,un effet identique est obtenu par des
read()
ou deswrite()
dans les fichiers;
d’une chaîne formatée ou aussi f-string) : c’est une forme de chaine de caractères
reconnaissable par le
f
ouF
qui précède le"
ou le'
d’ouverture de chaîne,et qui sera détaillée dans la section suivante.
On a indiqué que [type]
est le paramètre de format le plus important en pratique. C’est donc lui qui guide la présentation.
Formatage de nombres int
#
Le champs [type]
peut prendre les valeurs d
(par défaut), x
, X
, o
, et b
dont le sens est illustré par les 5 codes suivants.
type |
code ( |
format |
---|---|---|
int |
|
entier en base 10 (décimal) (par défaut) |
int |
|
entier en base 16 (hexa-décimal) en minuscules |
int |
|
entier en base 16 (hexa-décimal) en majuscules |
int |
|
entier en base 8 (octal) |
int |
|
entier en base 2 (binaire) |
Rmq. Ne pas se soucier du ‘0’ avant le ‘:’ qui débute le format.
print("22")
print(f"{22:d}")
print(f"{22:x}")
print(f"{22:X}")
print(f"{22:o}")
print(f"{22:b}")
22
22
16
16
26
10110
On verra avec la présentation des chaînes formatée qu’on peut formater des expressions évaluées à l’exécution – mais toujours comme des chaînes de caractères.
Le traitement suivant est similaire au précédent en introduisant une variable var
à (la valeur de) laquelle s’applique le formatage.
var = 22
print(var)
print(f"{var:d}")
print(f"{var:x}")
print(f"{var:X}")
print(f"{var:o}")
print(f"{var:b}")
22
22
16
16
26
10110
On illustre brièvement l’effet des champs [position]
et [largeur]
sur des décimaux.
var = 22
print(var, ": format par défaut du print")
print(f"{var:10d}", ": sur 10 caractères, alignement à droite par défaut pour 'int'")
print(f"{var:-^10d}", ": centré sur 10 caractères")
print(f"{var:.<10d}", ": aligné à gauche, 10 caractères complétés par des .")
22 : format par défaut du print
22 : sur 10 caractères, alignement à droite par défaut pour 'int'
----22---- : centré sur 10 caractères
22........ : aligné à gauche, 10 caractères complétés par des .
Les écritures classiques des entiers sont aussi obtenues à l’aide des codes suivants.
type |
code ( |
format |
---|---|---|
int |
|
entier en base 10 avec signe |
int |
|
entier en base 10 écrit avec |
int |
|
entier en base 16 avec |
int |
|
entier en base 8 avec |
int |
|
entier en base 2 avec |
var = 22
print(f"{var:+d}")
print(f"{var:0=4}")
print(f"{var:#X}")
print(f"{var:#o}")
print(f"{var:#b}")
+22
0022
0X16
0o26
0b10110
Formatage de nombres float
#
Le champs [type]
peut prendre les valeurs f
, e
, g
et %
.
Avec les champs [drapeau]
, [largeur]
et [précision]
, on obtient des formats adaptés aux float
.
type |
code ( |
format |
---|---|---|
float |
|
2 chiffres avant la virgule et 4 après |
float |
|
notation scientifique avec 5 chiffres après la virgule |
float |
|
un format générique “qui va bien” |
float |
|
pourcentage avec 2 décimales |
from math import pi as pi
print("pi=", pi)
print(f"{pi:2.3f}")
print(f"{pi:+.5e}")
print(f"{pi:g}")
print(f"{pi:*^+15.5e}")
pi= 3.141592653589793
3.142
+3.14159e+00
3.14159
*+3.14159e+00**
Rmq. Ces formatages d’int
et de float
apparaissent aussi dans d’autres langages de programmation, e.g. C.
Formatages de chaînes de caractères#
Dans ce cas, on défini les champs drapeau
et largeur
comme déjà indiqué.
type |
code ( |
format |
---|---|---|
str |
|
chaîne justifiée à gauche sur |
str |
|
chaîne justifiée à droite sur |
str |
|
chaîne centrée sur |
str |
|
chaîne centrée sur |
str |
|
chaîne justifiée à gauche sur |
s = "un texte formaté"
print(len(s))
print(f"{s:35}")
print(f"{s:>35}")
print(f"{s:^35}")
print(f"{s:+^35}")
16
un texte formaté
un texte formaté
un texte formaté
+++++++++un texte formaté++++++++++
Les caractères spéciaux \...
#
On rappelle que les caractères spéciaux ou séquences d’échappement sont l’association du “backslash” \
et de certains symboles (ou suite de symboles).
Cette suite de caractères (qui commence par \
) est interprétée de façon particulière.
Caractères spéciaux “de contrôle”:
\b
: backspace\t
\v
: tabulation horizontale ou verticale\n
: new line saut de ligne\f
: form feed saut de page\r
: retour en début de ligne
On a vu que le \
évite d’évaluer “normalement” le symbole qui le suit.
Donc :
\\
s’évalue comme le caractère\
,\'
ou\"
ou\/
comme les symboles'
ou"
ou/
et
\\n
comme la chaîne de 2 caractères non évalués\n
.
Retenons que \
permet de ne pas interpréter avec le sens réservé par les choix du langage de programmation le caractère qui le suit.
Il ramène au caractère ou à la chaîne de caractère écrites – et non son interprétation.
Cette notion se retrouve dans d’autres langages de programmation : C, …
Des fonctions plus générales qui résolvent ce type de problème sont présentées comme compléments en fin de chapitre.
print(“a\nb”)
9.1.2. Les expressions ou chaînes formatées#
Principe
On définit un format d’affichage pour une chaîne de caractères qui dépend de la valeur de certains champs à formater
On applique ce format à un nombre arbitraire de valeurs
On obtient un nombre arbitraire de valeurs affichées de la même manière.
Syntaxe :
f"une chaine de caractères qui contient au moins un {champs à formater}"
quantieme = 12
mois = "mars"
annee = 2021
temp = 18.2
s = f"La température du {quantieme} {mois} {annee} est {temp}oC."
print(s)
La température du 12 mars 2021 est 18.2oC.
L’intérêt de ces expressions (ou chaînes) formatées est mis en valeur en introduisant les formats d’affichage vus précédemment pour chaque champs et le type de valeur attendu.
Ces formats d’affichage commencent ici après le :
de chaque champs de l’expression formatée.
quantieme = 4
mois = 'mars'
annee = 2021
temp = 18.2
s1 = f"La température du {quantieme:2d} {mois:^10} {annee} est {temp:2.1f}oC."
# un entier sur 2 chiffres décimaux,
# une chaine centrée sur 10 caractères,
# un nombre flottant avec au plus 2 chiffres significatifs et une décimale
quantieme = 12
mois = 'janvier'
annee = 2021
temp = 5.58
s2 = f"La température du {quantieme:2d} {mois:^10} {annee} est {temp:2.1f}oC."
print(s1)
print(s2)
La température du 4 mars 2021 est 18.2oC.
La température du 12 janvier 2021 est 5.6oC.
9.1.3. La méthode .format()
.#
L’exemple précédent donne envie de pouvoir définir une fois pour toute l’expression formatée et de pouvoir l’appliquer à un nombre arbitraire de valeurs pour obtenir l’affichage formatée de ces valeurs.
C’est l’objet de la méthode .format()
qui s’applique à des str
.
La syntaxe de .format()
est un peu déroutante au début.
st_format.format(arg)
retourne une chaîne de caractèresstr
formatée
st_format
est une chaine de caractères qui définit le format d’affichage voulu : similaire à l’expression formatée, elle contient les champs délimitées par des{ }
qui intégrent éventuellement des spécifications de format.arg
est un conteneurtuple
oudict
oustr
de valeurs à formater.
Ainsi st_format.format(arg)
applique à arg
, les traitements définies entre { }
de la chaîne de définition du format st_format
.
Rmq.
Cette construction permet de définir “une fois pour toute” la chaîne
st_format
puis de l’appliquer à un nombre arbitraire d’arg
– ce qui n’est pas possible avec les expressions formatées f-strings.On rappelle que le type
str
est non-mutable – ce qui nous fait souvent préférer la dénomination expression formatée plutôt que chaîne formatée, traduction rapide du jargon python f-string.
Exemple. Une météo hasardeuse.
import random
le_format = "La température du {:2d} {:^10} {} est {:+5.1f} oC."
a = 2021
for m in ('janvier','février','mars'):
for q in range(1,28,4):
t = random.uniform(-2.0,15.9)
s = le_format.format(q, m, a, t)
print(s)
La température du 1 janvier 2021 est +3.9 oC.
La température du 5 janvier 2021 est +2.3 oC.
La température du 9 janvier 2021 est +8.3 oC.
La température du 13 janvier 2021 est +10.1 oC.
La température du 17 janvier 2021 est +7.2 oC.
La température du 21 janvier 2021 est +1.8 oC.
La température du 25 janvier 2021 est +12.6 oC.
La température du 1 février 2021 est +1.6 oC.
La température du 5 février 2021 est +6.3 oC.
La température du 9 février 2021 est +7.5 oC.
La température du 13 février 2021 est +0.9 oC.
La température du 17 février 2021 est +0.5 oC.
La température du 21 février 2021 est +4.6 oC.
La température du 25 février 2021 est +14.1 oC.
La température du 1 mars 2021 est +1.5 oC.
La température du 5 mars 2021 est +7.2 oC.
La température du 9 mars 2021 est -1.1 oC.
La température du 13 mars 2021 est -1.7 oC.
La température du 17 mars 2021 est +11.0 oC.
La température du 21 mars 2021 est +1.2 oC.
La température du 25 mars 2021 est +14.2 oC.
Le formatage de données textuelles s’applique aussi aux E-S sur fichiers.
Il est classique de mentionner que la méthode .format()
permet aussi d’effectuer des substitutions (des remplacements) de certaines parties de chaînes de caractères.
# formatage avec remplacement par st
le_format = "Le {} mot est {} {}"
st_formatee = le_format.format("premier", "très important", "....")
# affichage
print(st_formatee)
print(le_format)
# ecriture fichier
st1 = "capital, "
st2 = "assurément"
with open("./tmp/format1.txt", "w", encoding="utf8") as f:
f.write(st_formatee)
f.write("\n")
f.write(le_format.format("dernier", st1 + st2, "!"))
f.close()
Le premier mot est très important ....
Le {} mot est {} {}
!cat tmp/format1.txt
Le premier mot est très important ....
Le dernier mot est capital, assurément !
Rmq. Il est commode de voir la chaîne st_format
comme un masque de mise en forme qui va s’appliquer aux valeurs de l’argument arg
.
Cette utilisation par remplacement peut faire penser (à tort) à un rôle inversé de l’argument à formater arg
et de la chaîne st_format
qui définit le formatage.
Ce risque de confusion sera levée avec l’étude de la programmation objet (en python) – hors du programme de ce semestre.
9.1.4. (\(\star\)) Compléments#
Objectif 20 et en seconde lecture
str()
et repr()
#
Vous avez utilisé –de façon explicite ou “à votre insu”– la fonction str()
pour convertir une valeur de type quelconque en sa représentation comme une chaîne de caractères.
Citez un exemple d’utilisation implicite de
str()
La fonction str()
donne accès à la chaîne de caractères argument interprétée.
La fonction repr()
donne accès à la chaîne de caractères argument sans l’interpréter.
val = 22
s = str(val)
r = repr(val)
print(val, s, r, sep="*")
print(type(val), type(s), type(r))
print()
val = "\n"
s = str(val)
r = repr(val)
print(val, s, r, sep="*")
print(type(val), type(s), type(r))
print()
val = "\\n"
s = str(val)
r = repr(val)
print(val, s, r, sep="*")
print(type(val), type(s), type(r))
22*22*22
<class 'int'> <class 'str'> <class 'str'>
*
*'\n'
<class 'str'> <class 'str'> <class 'str'>
\n*\n*'\\n'
<class 'str'> <class 'str'> <class 'str'>
Lorsqu’aucun formatage particulier n’est souhaité, ces fonctions peuvent être utilisées avec les raccourcis suivants qui complètent les champs {}
des f-strings ou du formatage de .format()
.
!s
pourstr()
!r
pourrepr()
!a
pourascii()
mr_ou_mme = "Madame, \n Monsieur."
hello_s = f"Bonjour {mr_ou_mme!s}"
hello_r = f"Bonjour {mr_ou_mme!r}"
hello_a = f"Bonjour {mr_ou_mme!a}"
print(hello_s, hello_r, hello_a, sep="**")
Bonjour Madame,
Monsieur.**Bonjour 'Madame, \n Monsieur.'**Bonjour 'Madame, \n Monsieur.'
st = "Bonjour, \n bonjour !"
print(st)
print("{!s}".format(st))
print("{!r}".format(st))
print("{!a}".format(st))
Bonjour,
bonjour !
Bonjour,
bonjour !
'Bonjour, \n bonjour !'
'Bonjour, \n bonjour !'
Souplesses de l’arg
de .format()
.#
Avec .format()
, les arguments à formater peuvent être indiqués par position implicite (par défaut comme jusqu’à présent) ou explicite mais aussi par nommage ou par liste/dictionnaire – dans la définition et dans l’appel pour les deux derniers.
La position des valeurs du conteneur arg
argument de .format(arg)
est précisée dans les { }
de st_format
:
de façon explicite avec
{pos}
de façon nommée avec
{nom}
en correspondance avec l’item
i
d’un argumentlst
avec{0[i]}
en correspondance avec la valeur de
clé
d’un un argumentdict
avec{0[clé]}
Ces positions peuvent être complétées d’une spécification de formatage.
st_pos = "{1} {0} est {2}"
st_nom = "{article} {sujet} est {complement}"
st_lst = "{0[0]} {0[1]} est {0[2]}"
st_dict = "{0[article]} {0[sujet]} est {0[complement]}"
print(st_pos.format("ciel", "le", "bleu"))
print(st_nom.format(article="la", sujet="mer", complement="calme"))
print(st_lst.format( ["la", "montagne", "violette"] ))
d = dict(complement="chaud", article="le", sujet="soleil") # syntaxe dictionnaire param. nommés
print(st_dict.format(d))
le ciel est bleu
la mer est calme
la montagne est violette
le soleil est chaud
Méthodes spécifiques (sans .format()
)#
On verra que certains traitements peuvent être obtenus avec des méthodes spécifiques aux str
.
méthode |
effet |
---|---|
|
centre |
|
justifie |
|
justifie |
|
ajoute des zéros à gauche de |
9.2. Synthèse#
9.2.1. Avoir les idées claires#
Connaitre les principes du formatage des données pour pouvoir retrouver rapidement dans la documentation (de cours ou de référence) les commandes pour effectuer ce traitement.
9.2.2. Savoir-faire#
Utiliser les formatages de base des types
int
etfloat
de pythonEn s’appuyant sur les documents de cours ou de référence, définir et appliquer des formatages évolués et adaptés aux données manipulées avec python