7.1 Un Formatage de Sortie Plus Fantaisiste

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 :

>>> 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.elements():
...     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.