Il y a plusieurs manières de présenter l'affichage produit par un programme; les données peuvent être imprimées sous une forme humainement lisible, ou être écrites dans un fichier pour un usage ultérieur. Ce chapitre présentera certaines de ces possibilités.
Jusqu'ici nous avons rencontré deux manières d'afficher des valeurs:
les instructions d'expression et l'instruction print.
(Une troisième manière est d'utiliser la méthode write() des
objets fichier; le fichier de sortie standard peut être référencé
par sys.stdout
. Voyez le manuel Library Reference pour plus
d'informations.)
Vous souhaiterez souvent avoir plus de contrôle sur le formatage de
vos sorties que d'imprimer simplement des valeurs séparées par des
espaces. Il y a deux manières de formater vos sorties; la première
manière est de faire toutes les manipulations de chaînes de caractères
vous-même; en utilisant les opérations de concaténation et de
découpage de chaînes de caractères, vous pouvez créer n'importe quel
format que vous puissiez imaginer. Le module standard
string contient quelques opérations
utiles pour remplir des chaînes de caractères à une largeur de colonne
donnée; celles-ci seront discutées sous peu. La deuxième manière est
d'utiliser l'opérateur %
avec une chaîne de caractères comme
argument de gauche, %
interprète l'argument de gauche comme une
chaîne de formatage comme pour la fonction sprintf() du
langage C à appliquer à l'argument de droite, et retourne une
chaîne de caractères résultant de cette opération de formatage.
Il reste naturellement une question: comment convertissez-vous des valeurs
en chaînes de caractères? Heureusement, Python a un moyen de convertir
n'importe quelle valeur en chaîne de caractères: passez-la à la fonction
repr(), ou écrivez juste la valeur entre des guillemets
renversés (anti-quotes: ``
). Quelques exemples:
>>> x = 10 * 3.14 >>> y = 200*200 >>> s = 'La valeur de x est ' + `x` + ', et y est ' + `y` + '...' >>> print s La valeur de x est 31.4, et y est 40000... >>> # Les anti-quotes marchent avec d'autres types en dehors des nombres: ... p = [x, y] >>> ps = repr(p) >>> ps '[31.4, 40000]' >>> # Convertir une chaîne ajoute des quotes de chaîne et des antislash: ... salut = 'salut, monde\n' >>> saluts = `salut` >>> print saluts 'salut, monde\012' >>> # L'argument des anti-quotes peut être un tuple: ... `x, y, ('spam', 'eggs')` "(31.4, 40000, ('spam', 'eggs'))"
Voici deux manières d'écrire une table des carrés et des cubes:
>>> import string >>> for x in range(1, 11): ... print string.rjust(`x`, 2), string.rjust(`x*x`, 3), ... # Notez la virgule à la fin de la ligne précédente ... print string.rjust(`x*x*x`, 4) ... 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 >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 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
(Notez qu'un espace entre chaque colonne a été ajouté à cause de la façon dont print fonctionne: elle ajoute toujours des espaces entre ses arguments.)
Cet exemple présente la fonction string.rjust(), qui justifie à droite une chaîne de caractères dans un champ d'une largeur donnée en la complétant avec des espaces du côté gauche. Il y a les fonctions semblables string.ljust() et string.center(). Ces fonctions n'écrivent rien, elles renvoient juste une nouvelle chaîne de caractères. Si la chaîne de caractères d'entrée est trop longue, elles ne la tronquent pas, mais la renvoient sans changement; ceci gâchera votre présentation de colonne mais c'est habituellement mieux que l'alternative, qui serait de tricher au sujet d'une valeur. (Si vous voulez vraiment la troncature vous pouvez toujours ajouter une opération de découpage, comme "string.ljust(x, n)[0:n]".)
Il y a une autre fonction, string.zfill(), qui complète une chaîne de caractères numérique du côté gauche avec des zéros. Elle sait gérer les signes positifs et négatifs :
>>> import string >>> string.zfill('12', 5) '00012' >>> string.zfill('-3.14', 7) '-003.14' >>> string.zfill('3.14159265359', 5) '3.14159265359'
L'utilisation de l'opérateur %
ressemble à ceci:
>>> import math >>> print 'La valeur de PI est approximativement %5.3f.' % math.pi La valeur de PI est approximativement 3.142.
S'il y a plus d'un descripteur de format dans la chaîne de caractères, vous passez un tuple comme opérande de droite, par exemple.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> for nom, telephone in table.items(): ... print '%-10s ==> %10d' % (nom, telephone) ... Jack ==> 4098 Dcab ==> 8637678 Sjoerd ==> 4127
La plupart des formats fonctionnent exactement comme en C et
exigent que vous passiez le type approprié; cependant, si vous ne le
faites pas vous obtenez une exception, pas un core dump. Le format de
%s
est moins strict : si l'argument correspondant n'est pas un
objet chaîne de caractères, il est converti en chaîne de caractères en
utilisant la fonction intégrée str(). Utiliser *
pour passer la largeur ou la précision comme argument (entier) séparé
est possible. Les formats %n
et %p
du C ne sont pas
supportés.
Si vous avez une chaîne de caractères de formatage vraiment longue que
vous ne voulez pas fractionner, il serait élégant de pouvoir
référencer les variables à formater par leur nom et pas par leur
position. Ceci peut être fait en utilisant une extension des formats
du C en utilisant la forme %(name)format
, par exemple.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table Jack: 4098; Sjoerd: 4127; Dcab: 8637678
C'est particulièrement utile en combinaison avec la fonction intégrée vars(), qui renvoie un dictionnaire contenant toutes les variables locales.
open() renvoie un objet de type fichier, et est utilisée plus généralement avec deux arguments: "open(nomfichier, mode)".
>>> f=open('/tmp/fichiertravail', 'w') >>> print f <open file '/tmp/fichiertravail', mode 'w' at 80a0960>
Le premier argument est une chaîne de caractères contenant le nom du
fichier. Le deuxième argument est une autre chaîne de caractères
contenant quelques caractères décrivant la manière d'utiliser le
fichier. mode vaut 'r'
quand le fichier doit être
seulement lu, 'w'
pour seulement écrit (un fichier déjà existant
avec le même nom sera effacé), et 'a'
ouvre le fichier en
ajout; les données écrites dans le fichier seront
automatiquement ajoutées à la fin. 'r+'
ouvre le fichier pour
la lecture et l'écriture. L'argument mode est facultatif;
'r'
sera pris par défaut s'il est omis.
Sur Windows et Macintosh, 'b'
ajouté au mode ouvre fichier en
mode binaire, donc il y a aussi des modes comme 'rb'
,
'wb'
, et 'r+b'
. Windows fait la distinction entre
fichier texte et binaire ; les caractères de fin de ligne dans des
fichiers texte sont automatiquement modifiés légèrement quand des
données sont lues ou écrites. Cette modification imperceptible des
données du fichier marche très bien pour des fichiers textes ASCII,
mais elle altèrera des données binaires comme dans des fichiers JPEG
ou .EXE. Faites très attention à utiliser le mode binaire en
lisant et en écrivant de tels fichiers. (notez que la sémantique
précise du mode texte sur le Macintosh dépend de la bibliothèque C
utilisée.)
Le reste des exemples dans cette section supposera qu'un objet fichier
appelé f
a déjà été créé.
Pour lire le contenu d'un fichier, appeler
f.read(taille)
, qui lit une certaine quantité de données
et les retourne en tant que chaîne de caractères. taille est un
argument numérique facultatif. Quand taille est omis ou
négatif, le contenu entier du fichier sera lu et retourné; c'est votre
problème si le fichier est deux fois plus grand que la mémoire de
votre machine. Autrement, au plus taille octets sont lus et
retournés. Si la fin du fichier a été atteinte, f.read()
renverra une chaîne de caractères vide (""
).
>>> f.read() 'Ceci est le fichier entier.\012' >>> f.read() ''
f.readline()
lit une seule ligne à partir du fichier; un
caractère de fin de ligne (\n
) est laissé à l'extrémité de la
chaîne de caractères lue, et est seulement omis sur la dernière ligne
du fichier si le fichier ne se termine pas par une fin de ligne. Ceci
rend la valeur de retour non ambiguë; si f.readline()
renvoie
une chaîne de caractères vide, la fin du fichier a été atteinte, alors
qu'une fin de ligne est représentée par '\n'
, une chaîne de
caractères contenant seulement une seule fin de ligne.
>>> f.readline() 'Ceci est la première ligne du fichier.\012' >>> f.readline() 'Deuxième ligne du fichier\012' >>> f.readline() ''
f.readlines()
utilise f.readline()
de façon répétitive,
et retourne une liste contenant toutes les lignes de données du
fichier.
>>> f.readlines() ['Ceci est la première ligne du fichier.\012', 'Deuxième ligne du fichier\012']
f.write(chaine)
écrit le contenu de chaine dans le
fichier, en retournant None
.
>>> f.write('Voici un test\n')
f.tell()
renvoie un nombre entier donnant la position actuelle
dans le fichier associé à l'objet fichier, mesurée en octets depuis
le début du fichier. Pour changer la position dans l'objet fichier,
employez "f.seek(decalage, point_depart)". La
position est calculée en ajoutant decalage à un point de
référence; le point de référence est choisi par l'argument
point_depart. Une valeur de 0 pour point_depart fait
démarrer au début du fichier, 1 utilise la position courante du
fichier, et 2 utilise la fin de fichier comme point de référence.
point_depart peut être omis et prend alors 0 pour valeur par
défaut comme point de référence.
>>> f=open('/tmp/fichiertravail', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) # Saute jusqu'au 5ème octet dans le fichier >>> f.read(1) '5' >>> f.seek(-3, 2) # Saute jusqu'au 3ème octet avant la fin >>> f.read(1) 'd'
Quand vous en avez terminé avec un fichier, appeler f.close()
pour le fermer et libérer toutes les ressources système utilisées par
le fichier ouvert. Après avoir appelé f.close()
, les
tentatives d'utiliser l'objet fichier échoueront automatiquement.
>>> f.close() >>> f.read() Traceback (innermost last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
Les objets fichier ont quelques méthodes supplémentaires, telles que isatty() et truncate() qui sont moins fréquemment utilisées; consultez la Library Reference pour un guide complet des objets fichier.
Les chaînes de caractères peuvent facilement être écrites et lues dans
un fichier. Les nombres demandent un peu plus d'effort, puisque la
méthode read() renvoie seulement les chaînes de caractères,
qui devront être passées vers une fonction comme
string.atoi(), qui prend une chaîne de caractères comme
'123'
et renvoie sa valeur numérique 123. Cependant, quand
vous voulez sauvegarder des types de données plus complexes comme des
listes, des dictionnaires, ou des instances de classe, les choses
deviennent beaucoup plus compliquées.
Plutôt que faire écrire et déboguer constamment par les utilisateurs le code pour sauvegarder des types de données complexes, Python fournit un module standard appelé pickle. C'est un module étonnant qui peut prendre presque n'importe quel objet Python (même quelques formes de code Python!), et le convertir en une représentation sous forme de chaîne de caractères; ce processus s'appelle pickling. Reconstruire l'objet à partir de sa représentation en chaîne de caractères s'appelle unpickling. Entre pickling et unpickling, la chaîne de caractères représentant l'objet a pu avoir été enregistrée dans un fichier ou des données, ou avoir été envoyée à une machine éloignée via une connexion réseau.
Si vous avez un objet x
, et un objet fichier f
ouvert en
écriture, la voie la plus simple de ``pickler'' l'objet prend seulement
une ligne de code:
pickle.dump(x, f)
Pour ``unpickler'' l'objet, si f
est un objet fichier ouvert en lecture:
x = pickle.load(f)
(il y a d'autres variantes pour ceci, utilisées pour ``pickler'' beaucoup d'objets ou quand vous ne voulez pas écrire les données ``picklées'' dans un fichier; consultez la documentation complète pour pickle dans la Library Reference.)
pickle est le moyen standard pour enregistrer des objets Python et les réutiliser dans d'autres programmes ou dans une future invocation du même programme; le terme technique pour ceci est la persistance d'un objet. Puisque pickle est très largement répandu, beaucoup d'auteurs qui écrivent des extensions pour Python prennent soin de s'assurer que de nouveaux types de données tels que des matrices peuvent être correctement ``picklés'' et ``unpicklés''.