Présentation, opérations, conversions¶
Les chaînes : premier contact¶
La notion de chaîne¶
Les chaînes de caractères permettent de stocker du texte. En première approximation, une chaîne est une succession de caractères imprimables. Cela peut être, par exemple, une phrase ou un groupe de mots, comme Le nombre 42 est magique.
On dit souvent chaîne au lieu de chaîne de caractères.
De la même façon qu’un programme peut travailler avec des entiers, il peut travailler avec des chaînes.
Sensibilité à la casse¶
La casse d’un caractère alphabétique est le fait que le caractère soit en majuscule ou en minuscule.
Les chaînes bonjour et bonJour sont considérées en Python comme distinctes. Si deux chaînes ont, à des positions identiques, des lettres de casses différentes, les chaînes sont considérées comme distinctes.
Chaîne littérale¶
Le moyen le plus immédiat d’utiliser des chaînes dans un code Python est par le biais d’une chaîne littérale :
1 2 3 4 5 | s = "orange"
print(len(s))
t = 'rose'
print(len(t))
|
6 7 | 6
4
|
À la ligne 1, on lit "orange"
: c’est une chaîne, dite littérale. A la ligne 2, on demande l’affichage du nombre de caractères de la chaîne. On lit à la ligne 6 la longueur de la chaîne.
Une chaîne est littérale lorsque
- tous ses caractères sont placés dans le code-source,
- la chaîne est encadrée par des caractères particuliers, appelés quotes, ici des guillemets anglo-saxons (mais il existe d’autres délimiteurs possibles).
Afficher une chaîne¶
Pour afficher une chaîne avec une « commande » Python, on utilisera obligatoirement la fonction print
:
1 2 3 | fruit = "orange"
print(fruit)
print("bonjour")
|
4 5 | orange
bonjour
|
- Lignes 2 et 4: ici, on affiche une chaîne par l’intermédiaire d’une variable.
- Lignes 3 et 5 : affichage direct d’une chaîne littérale.
- On notera que les délimiteurs de chaîne ne sont pas affichés.
Dans certains environnement (mode interactif, cellule Jupyter Notebook), une chaîne peut être affichée sans recours à la fonction print
.
Erreur courante de débutant¶
Pour afficher une chaîne littérale, on fera attention de ne pas oublier les quotes autour de la chaîne :
print(bonjour)
NameError: name 'bonjour' is not defined
La notion de caractère¶
L’unité fondamentale d’un texte est le caractère. Un mot, une phrase est composée de caractères. On peut disposer de certains caractères en les plaçant entre guillemets, par exemple la lettre "Y"
qui est en fait une chaîne d’un seul caractère (alors qu’on en écrit trois dans le code si on compte les deux guillemets).
Parmi les caractères, on trouve les caractères alphabétiques majuscules ou minuscules mais aussi tous les caractères de ponctuation, les chiffres, par exemple le chiffre "8"
.
On dispose aussi de caractères invisibles comme l’espace " "
(taper sur la barre d’espace) ou encore le saut de ligne. Le blanc souligné _
est aussi un caractère très utilisé. Il existe aussi des caractères non imprimables et qui peuvent se retrouver dans une chaîne.
Python supporte l’encodage UTF-8 et donne donc accès à tous les caractères imaginables.
En pratique, dans un cours de débutant sur les chaînes de caractères, on essaye de ne pas avoir à utiliser des caractères tels que le guillemet ou l’apostrophe car ils ont rôle spécial pour construire des chaînes dites littérales.
La notion de chaîne littérale¶
Une chaîne littérale est un chaîne de caractères saisie telle quelle dans le code-source entre une paire de délimiteurs. Ainsi, "orange"
est une chaîne littérale, le délimiteur étant ici un guillemet :
s = "orange"
print(s)
orange
Les délimiteurs ne font pas partie du contenu d’une chaîne littérale, comme on le voit à l’affichage.
Insistons : une chaîne littérale n’a de sens que dans un code-source puisque littéral veut dire qui s’interprète littéralement autrement dit, « lettre à lettre », et c’est bien comme cela qu’elle apparaît dans le code-source Python.
Le délimiteur de chaîne littérale le plus familier est le guillemet anglais "
. Mais un autre délimiteur usuel est l’apostrophe :
1 2 3 4 | s = "rose"
t = 'rose'
print(s)
print(t)
|
5 6 | rose
rose
|
- Ligne 1 : chaîne littérale entourée de guillemets
- Ligne 2 : chaîne littérale entourée d’apostrophes
- Lignes 5-6 : les chaînes
s
ett
sont égales.
Pour ce qui est du contenu d’une chaîne, par défaut, les caractères d’une chaîne Python (littérale ou pas d’ailleurs) appartiennent au jeu Unicode et donc peuvent comporter des accents ou être des caractères spéciaux. Par exemple, la chaîne littérale s
suivante est valide :
s = "Les pièces de 5€ n'existent pas"
print(s)
Les pièces de 5€ n'existent pas
Opérations sur des chaînes¶
On peut faire de nombreuses opérations sur les chaînes. Voici juste quelques exemples et qui seront détaillés ailleurs.
Nombre de caractères¶
Déterminer avec la fonction standard len
le nombre de caractères d’une chaîne, ce qu’on appelle sa longueur :
1 | print(len("anticonstitutionnellement"))
|
2 | 25
|
- Ligne 1 : la fonction standard
len
, fournie par Python, effectue le calcul de la longueur.
Concaténer deux chaînes¶
L’opérateur +
permet de mettre bout à bout deux chaînes :
1 | print("bon" + "Jour")
|
2 | bonJour
|
- Ligne 1 : la concaténation (c’est le terme consacré) est effectuée avec l’opérateur
+
. - Ligne 2 : noter que les deux chaînes bon et Jour sont placées bout à bout, sans espace entre les chaînes.
Détail : l’expression "bon" + "Jour"
est la concaténation de deux chaînes littérales et n’est pas une chaîne littérale.
Chaîne vide¶
Une chaîne peut être vide autrement dit ne contenir aucun caractère. Une chaîne vide peut être représentée par la chaîne littérale ""
(deux guillemets collés l’un à l’autre et qui n’entourent rien). La chaîne vide est de longueur nulle :
vide = ""
print(len(vide))
0
La chaîne vide peut aussi être notée ''
c’est-à-dire deux apostrophes côte-à-côte, sans espace entre les deux apostrophes :
vide = ''
# une chaîne vide a une longueur nulle
print(len(vide))
0
La chaîne vide a de nombreux usages (comme le chiffre zéro en a !). Par exemple, une chaîne vide peut être utilisée pour supprimer des caractères à l’intérieur d’une chaîne en remplaçant les caractères par une chaîne vide.
Le caractère espace¶
De même qu’il existe un caractère A
désignant la lettre A
, il existe un caractère espace, celui obtenu en tapant sur la barre d’espaces. Plus précisément, le contenu de la chaîne " "
est un espace :
1 2 3 | print("Bug" + "2038")
print("Bug" + " " + "2038")
print("Bug 2038")
|
4 5 6 | Bug2038
Bug 2038
Bug 2038
|
- Ligne 1 : Les chaînes
"Bug"
et"2038"
sont concaténées sans insertion d’espace. - Lignes 2 et 3 : les chaînes affichées sont identiques : l’espace peut-être considéré comme une chaîne littérale (ligne 2) ou immergé dans la chaîne (ligne 3).
Invisible n’est pas vide¶
La chaîne " "
n’est pas vide, elle contient exactement un caractère :
espace = " "
print(len(espace))
1
Le caractère espace sert aussi à créer une indentation en plaçant des « blancs » en début de lignes. Pour dessiner en mode texte, la figure ci-dessous :
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
#
#
il faut placer des caractères espace en début de ligne.
Le caractère saut de ligne¶
Dans beaucoup de langages de programmation, y compris Python, le codage du caractère saut de ligne est noté \n
. L’usage de ce groupe de deux caractères permet effectivement de signifier un saut de ligne dans une chaîne (littérale) :
s = "Lundi\nMardi\nMercredi"
print(s)
Lundi
Mardi
Mercredi
On notera que le caractère saut de ligne \n
n’a pas de raison d’être d’être suivi d’un espace littéral qui provoquerait un effet peut-être non désiré :
1 2 | s = "Lundi\n Mardi\nMercredi"
print(s)
|
3 4 5 | Lundi
Mardi
Mercredi
|
- Ligne 1 : noter l’espace dans le code source, dans la chaîne littérale, juste avant le mot Mardi.
- Ligne 4 : l’espace est compté dans la chaîne et visible à l’affichage.
Bien que le caractère littéral représentant un saut de ligne s’écrive avec deux caractères, ces deux caractères sont insécables et ils comptent pour un caractère dans la longueur de la chaîne vue comme objet Python. Ainsi :
s="rose\nbleu"
print(s)
print(len(s))
rose
bleu
9
Plusieurs sauts de ligne¶
Pour aérer un texte, on peut souhaiter y placer plusieurs sauts de ligne l’un après l’autre. Si on place côte-à-côte deux caractères \n
, on effectue deux passages à la ligne, ce qui va créer une ligne blanche :
texte = "rose\n\nkiwi"
print(texte)
rose
kiwi
Une ligne blanche n’est jamais vide et est constituée d’au moins un caractère, le saut de ligne et éventuellement des espaces en début de ligne.
Concaténation et répétition de chaînes¶
On peut concaténer des chaînes, c’est-à-dire les mettre bout à bout. La concaténation de chaînes est effectuée avec l’opérateur +
:
1 2 3 4 5 6 | a = "Rose"
b = "Rouge"
c = "Rome"
s = a + b + c
print(s)
print(a, b, c)
|
7 8 | RoseRougeRome
Rose Rouge Rome
|
- Ligne 4 :
s
est la concaténation des chaînesa
,b
etc
. - Lignes 5 et 8 : la concaténation des chaînes crée une nouvelle chaîne et préserve les chaînes initiales.
On peut aussi concaténer n
fois une chaîne avec elle-même avec l’opérateur *
1 2 3 4 5 | a = "Rose"
r = 3 * a
print(r)
print(a * 3)
print(2 * a *2)
|
6 7 8 | RoseRoseRose
RoseRoseRose
RoseRoseRoseRose
|
- Ligne 3 ou 4 :
a
est répétée 3 fois - Lignes 5 : on peut multiplier des deux côtés.
On peut aussi panacher addition et multiplication :
a = "Rose"
b = "Rouge"
c = "Rome"
s = 2 * (c + a + ' ') + 2 * (c + b + ' ')
print(s)
RomeRose RomeRose RomeRouge RomeRouge
Concaténation et produit par zéro¶
L’opération 0 * s
renvoie la chaîne vide et 1 * s
. On peut en déduire une astuce pour mettre un nom au pluriel en ajoutant, selon l’effectif, un "s"
terminal :
for val in (0, 1, 7):
print(val, "bille" + (val > 1)*"s")
0 bille
1 bille
7 billes
Voici 3 autres façons de réaliser la même opération
for val in (0, 1, 7):
print(val, "bille" + ["s", ""][val < 2])
print("---------------")
for val in (0, 1, 7):
print(val, "bille" + ("" if val < 2 else 's'))
print("---------------")
for val in (0, 1, 7):
print(val, f"bille{'s'[val<2:]}")
et qui affiche :
0 bille
1 bille
7 billes
---------------
0 bille
1 bille
7 billes
---------------
0 bille
1 bille
7 billes
Chaînes égales¶
L’opérateur ==
permet de comparer deux chaînes pour savoir si elles ont ou pas exactement les mêmes caractères et dans le même ordre :
1 2 3 4 | print("ROSE" == "R0SE")
print("RoseRose" == "Rose" + "Rose")
print("Rose" == "rose")
print("ROSE" == 'ROSE')
|
5 6 7 8 | False
True
False
True
|
- Ligne 1 : Malgré les apparences, les chaînes sont distinctes : à l’indice 1, l’une utilise la lettre
O
majuscule et l’autre un zéro. - Ligne 2 :
"Rose" + "Rose"
est la concaténation de deux chaînes. - Ligne 3 : Pour que deux caractères soient égaux, il faut déjà qu’ils aient la même casse, ce qui n’est pas le cas de la lettres initiale.
- Ligne 4 : Des délimiteurs apostrophes ou guillemets n’ont pas d’influence sur l’égalité de chaînes.
Attention que l’égalité de deux chaînes est une opération ayant une complexité cachée. En effet, pour savoir si deux chaînes sont égales ou pas, l’interpréteur Python compare terme à terme les éléments des deux chaînes jusqu’à ce que deux caractères soints distincts ou bien qu’une des chaînes ne possède plus d’élément à examiner.
Donc la comparaison de deux chaînes de longueur chacune 1000, peut nécessiter jusqu’à 1000 comparaisons. Ainsi, l’opérateur ==
entre deux chaînes peut être coûteux (en réalité, c’est moins simple que ça, cf. implicit Interning).
Accès aux caractères d’une chaîne¶
On peut accéder en lecture individuellement aux caractères d’une chaîne à l’aide d’un indice entier :
p = "Jupiter"
# le premier caractère de la chaîne p
print(p[0])
# le troisième caractère de la chaîne p
print(p[2])
# la longueur de la chaîne
n = len(p)
print(n)
# Dernier caractère de la chaîne p
print(p[n - 1])
J
p
7
r
Les caractères d’une chaînes sont numérotés de la gauche vers la droite. Ces numéros sont appelés des indices ; la numérotation commence à 0 (et non pas à 1) et se termine à n-1
où n
désigne le nombre total de caractères.
On accède à chaque caractère de la liste avec l’opérateur []
d’indexation.
Le fait de pouvoir accéder à tous les caractères d’une chaîne par des entiers consécutifs se traduit en disant que les chaînes de caractères sont du type séquence.
Il est possible d’utiliser des indices négatifs, ce qui est parfois à l’origine de bugs pour ceux qui ne connaissent pas leur existence.
Chaîne vs liste des caractères¶
On recontre parfois dans du code d’apprentis codeurs des « chaînes » définies par la liste de leurs caractères, cf. 1re ligne ci-dessous :
1 2 3 | s = ['C', 'H', 'O', 'C', 'O', 'L', 'A', 'T']
print(len(s))
print(s[0])
|
4 5 | 8
C
|
Il se trouve que (lignes 4 et 5) la longueur de la chaîne est donnée correctement ainsi que le premier caractère. Une tournure ici équivalente serait d’utiliser une chaîne littérale :
s = "CHOCOLAT"
print(len(s))
print(s[0])
En pratique, on rencontre souvent la liste des lettres de l’alphabet :
alpha = ['A', 'B', 'C', 'D', etc]
Bien que la tournure ne soit pas forcément incorrecte (en particulier si on a besoin de modifier une chaîne), la plupart du temps ce n’est pas justifié. La saisie de la chaîne est beaucoup plus laborieuse que sous forme de chaîne littérale, la chaîne est moins facilement lisible, on n’a pas une chaîne mais une liste, donc on ne dispose pas des méthodes de chaînes, l’appartenance n’est pas définie de la même façon, par exemple :
s = ['C', 'H', 'O', 'C', 'O', 'L', 'A', 'T']
print("" in s)
s = "CHOCOLAT"
print("" in s)
False
True
Dépassement d’indice dans une chaîne¶
Comme pour les listes, un indice de chaîne trop grand entraîne la levée d’une exception :
1 2 3 4 | z = "orange"
c = z[10]
print(c)
|
5 6 | c = z[10]
IndexError: string index out of range
|
- Ligne 6 : une erreur d’indice est signalée
- Ligne 2 : la variable
c
désignerait le caractère à l’indice 10 alors que l’indice maximal dansc
est 5 puisque la chaînez
est de longueur 6. - Ligne 2 : L’opération
z[10]
est en fait interdite, on tente d’accéder en lecture à un caractère qui n’existe pas. - Lignes 5-6 : Le message d’erreur explique que l’indice 10 est en dehors de la plage d’indices possibles.
Tenter d’accéder en simple lecture à un caractère d’une chaîne avec un indice ne correspondant pas à un élément de la chaîne conduit à une erreur, de type indexError
et qualifiée de débordement d’indice. C’est le même problème que pour les listes.
Boucle for : parcours de chaînes¶
Une chaîne est une séquence et peut être parcourue, sans indice, par une boucle for
. Voici un exemple de parcours d’une chaîne avec une boucle for :
for c in "ALIBABA":
print(c*2)
AA
LL
II
BB
AA
BB
AA
C’est le même principe que pour les listes, il est possible de faire un parcours sans recourir à un indice.
Il est aussi possible de parcourir la chaîne par indices :
s="ALIBABA"
for i in range(len(s)):
print(s[i]*2)
AA
LL
II
BB
AA
BB
AA
Cela peut être justifié dans certaines situations (par exemple si on doit comparer un caractère au suivant ou au précédent) où l’usage recommande d’utiliser enumerate
, voir cette explication.
Comparaison alphabétique de chaînes¶
Les différents opérateurs de comparaison (par exemple <
ou >=
) permettent d’effectuer certaines comparaisons alphabétiques de chaînes :
print("prune" < "rose")
True
Si les chaînes ont la même casse (soit les deux en minuscule, soit les deux en majuscule) et sont dépourvues de caractères spéciaux ou d’accents, ces comparaisons correspondent à ce qui est attendu. En effet, l’opérateur de comparaison appliqué à des chaînes compare les codes unicodes des chaînes. Ces codes ne correspondent que partiellement à l’ordre alphabétique usuel. Pour des chaînes de casses différentes ou utilisant des caractères spéciaux, les comparaisons sont parfois contraires à l’ordre usuel :
print("prune" < "Rose")
print("été"< "printemps")
False
False
Pour comparer deux chaînes en tenant compte des accents, voir le paragraphe intitulé Comparaison alphabétique de chaînes unicodes.
La fonction repr
¶
La notion exposée dans ce paragraphe n’est pas forcément adaptée à quelqu’un ayant peu d’expérience en Python.
La fonction repr
est une fonction standard. Voici un exemple commenté d’utilisation de cette fonction :
1 2 3 4 5 | X = "rose"
code = repr(X)
print(code)
print(X)
print(len(code))
|
6 7 8 | 'rose'
rose
6
|
- Ligne 1 : la fonction
repr
peut prendre en argument n’importe quel objet Python (un entier, une liste, une fonction, etc), ici une chaîne (qui est littérale ici mais ça n’a aucune importance) ; - Ligne 2 : la variable
code
est ici une chaîne de caractères. Le contenu de cette chaîne est exactement un code Python d’un objet qui vaudraitX
. - Ligne 6 : on observera la présence d’apostrophes au début et en fin de chaîne, cela va être expliqué ci-dessous.
- Ligne 7 : par contraste, on observera l’absence de séparateur (apostrophe ou guillemet) dans l’affichage de
X
- Ligne 8 :
code
n’est pas la chaîne rose ; cette dernière est de longueur 4 alors quecode
est une chaîne de longueur 6 :code
est en fait une chaîne littérale, donc le premier caractère decode
n’est pas ler
derose
mais une apostrophe (délimiteur de chaîne littérale).
Ainsi, la fonction repr
appliquée à un objet Python X
(par exemple un entier, une chaîne, une liste, etc) renvoie une chaîne dont le contenu, s’il était placé dans du code Python, serait évalué en l’objet X
. Le nom repr
vient du fait que la fonction renvoie une représentation de l’objet sous forme de chaîne.
Pour dire les choses simplement, repr
transforme des objets Python en du code Python.
Ne pas s’inquiéter si cette notion n’est pas totalement claire, elle peut nécessiter d’avoir pas mal travaillé avec du code Python pour bien être comprise.
La fonction repr
ressemble beaucoup à la fonction print
dans la mesure où, dans la plupart des cas, l’affichage de ce que renvoie repr
est strictement identique à l’affichage produit par la fonction print :
print(repr(42))
print(42)
42
42
Il y a une nuance essentielle pourtant : la fonction print
appliquée à un objet se contente de fournir une représentation uniquement visuelle d’un objet (la fonction print
affiche à l’écran et ne retourne rien) tandis que la fonction repr
renvoie une chaîne représentant l’objet.
La présentation ci-dessus est simplifiée. Il se peut très bien que repr
ne renvoie pas une chaîne de code Python exécutable. Par exemple,
print(repr(print))
<built-in function print>
et les cas de ce type sont nombreux. La documentation officielle de la fonction : repr. La définition donnée n’est pas claire et la documentation n’indique pas quand la chaîne retournée est directement exécutable ou pas.
La classe str
¶
Toutes les chaînes de caractères sont des instances de la classe str
qui représente le type string en Python. La classe str
peut être utilisée comme « constructeur » ie un appel de la forme str(v)
où v
est un objet Python retourne (construit) une chaîne qui permet d’afficher v
. Par exemple :
1 2 3 4 | s = str(6 * 7)
print(s)
print(s[0])
|
5 6 | 42
4
|
- Ligne 1 : le constructeur
str
est appelé sur l’entier 42 - Ligne 4 :
s
est l’interprétation parstr
de l’entier 42. Il s’agit de la chaîne"42"
. - Lignes 3 et 5 :
s[0]
n’est donc que le premier chiffre de 42 vu comme comme un caractère, à savoir le chiffre"4"
.
C’est anecdotique mais un appel str()
renvoie une chaîne vide.
La fonction print
est fortement liée à la fonction str
: en effet, la fonction print
appliquée à un objet X
affiche la chaîne renvoyée par str(X)
.
Conversion d’un nombre en chaîne avec le type str
¶
Dans certaines situations, un nombre x
, par exemple entier ou flottant, a besoin d’être vu moins comme un nombre que comme la suite des chiffres décimaux qui composent x
, chaque chiffre (décimal) étant alors vu comme un caractère. Le type natif str
permet de convertir un nombre en chaîne.
Soient des questions telles que :
- trouver le nombre de chiffres d’un nombre, par exemple 458 a 3 chiffres
- calculer la somme des chiffres d’un nombre, par 458 a pour somme des chiffres 17
- récupérer le premier chiffre d’un nombre, par exemple 4523012 a pour premier chiffre 4
- changer un point par une virgule, par exemple 3.14 -> 3,14
Pour ce genre de programme, il est préférable de voir les nombres comme chaînes de caractères.
Fonction str
de conversion¶
Voici un exemple d’utilisation :
1 2 3 | print(str(42))
print(str(3.14))
print(str(75 + 30))
|
4 5 6 | 42
3.14
105
|
- Ligne 1
str
prend ici un entier en argument et renvoie sa conversion en caractères (en chiffres décimaux). En particulier,str(42)
est la chaîne de caractères 42 - Ligne 2 : le type natif
str
convertit également des flottants. - Lignes 3 et 6 : noter que l’argument
75 + 30
est d’abord évalué en l’entier105
avant d’être converti en la chaîne 105.
Le type natif str
s’utilise comme une fonction : on parlera donc de fonction str
même s’il s’agit plutôt d’un type.
Signalons qu’effectuer la conversion d’un nombre vers sa représentation décimale nécessite un travail qui n’est pas complètement trivial même si l’idée est simple (faire des divisions entières successives par 10). Le code de l’implémentation en C se trouve ici, cf. la fonction long_to_decimal_string_internal
.
La Référence du langage indique seulement depuis sa version 3.8 que la représentation se fait en base 10, si possible.
Utilisations de la fonction str
¶
Voici quelques exemples d’utilisation de la fonction str
.
Nombre de chiffres¶
Pour calculer le nombre de chiffres d’un nombre entier, on peut utiliser la fonction str
:
1 2 3 4 | x = 2038 * 2 ** 10
ch = str(x)
print(len(ch))
print(x)
|
5 6 | 7
2086912
|
- Ligne 2 : on convertit l’entier en chaîne et la fonction
len
compte le nombre de caractères de la chaîne, ce qui donne le nombre de chiffres (en base 10, toujours). - Ligne 6 : en calculant explicitement
x
, on vérifie visuellement quex
a bien 7 chiffres.
Changer le point décimal en virgule¶
Pour transformer par exemple le nombre 3.14
en sa représentation à virgule 3,14
on transforme d’abord le flottant 3.14
en chaîne puis on remplacera le point par une virgule dans la nouvelle chaîne :
x = 3.14
z = str(x)
zz = z.replace(".", ",")
print(zz)
3,14
- Noter que
zz
est une chaîne de caractères
Limitation de la conversion en chaîne¶
Il faut prendre garde qu’une fois un nombre x
converti en chaîne s
, il n’est plus possible d’effectuer directement des opérations numériques sur s
car les chiffres sont en fait des caractères et non des entiers.
Par exemple, supposons que l’on cherche à afficher les chiffres pairs d’un entier ; si x = 53421
alors les chiffres pairs sont 4
et 2
. Alors, on ne pourra pas tester la parité du chiffre avec l’opération % 2
:
x = 53421
s = str(x)
for c in s:
if c % 2 == 0:
print(c)
if c % 2 == 0:
TypeError: not all arguments converted during string formatting
Pour y parvenir, il faudrait reconvertir les chiffres en entiers en utilisant int
. On aurait le même type de problème s’il fallait calculer la somme des chiffres.
Conversion d’une chaîne en entier¶
Il ne faut pas confondre un nombre entier et la chaîne qui le représente. Par exemple, les objets Python "2042"
et 2042
s’affichent de la même façon :
a = "2042"
print(a)
b = 2042
print(b)
2042
2042
mais ils sont bien distincts : le premier objet est de type chaîne de caractères et le second est de type entier.
C’est quoi le problème ?¶
Voici un exemple de situation où l’on a besoin de convertir une chaîne en nombre : soit un programme qui, à partir d’une date donnée sous forme de chaîne de caractères et sous un certain format, par exemple 31/12/2042
, doit retourner la date du lendemain, ici 01/01/2043
(sous forme de chaîne, toujours). Pour résoudre le problème, il faut extraire de la date les éléments suivants :
- le jour (ici 31),
- le mois (ici 12),
- l’année (ici 2042)
qui sont des sous-chaînes et effectuer des opérations sur ces objets vus comme des entiers, par exemple une addition, ici \(2042+1=2043\), d’où la nécessité de convertir la chaîne en nombre entier, car la somme des chaînes "2042" +"1"
ne donne pas le résultat attendu :
print("2042" + "1")
20421
La fonction de conversion int
¶
Pour convertir une chaîne représentant un entier écrit en base 10 en l’entier correspondant, on utilise le type intégré int
:
1 2 | a = "2042"
print(int(a) + 1)
|
3 | 2043
|
- Ligne 2 :
int(a)
vaut l’entier représenté en base 10 par la chaîne « 2042 » c’est-à-dire le nombre2042
. Il est donc licite d’ajouter1
àint("2042")
.
int
désigne le type int
(c’est-à-dire le type entier) mais peut aussi être utilisé comme une fonction. On parlera donc de fonction int
même s’il s’agit plutôt d’un type.
Remarquer que l’opération suivante :
"2042" + 1
n’a pas de sens en Python :
a = "2042"
print(a + 1)
print(a + 1)
TypeError: Can't convert 'int' object to str implicitly
Précautions¶
On prendra garde qu’une fois une chaîne s
convertie en nombre entier x
, les opérations de chaînes sur x
ne sont plus permises (elles n’ont pas de sens). Par exemple, si un nombre x
est écrit sous forme de chaîne s
alors s[0]
représente le premier chiffre de x
, un chiffre étant ici vu comme un caractère. En revanche, l’opération x[0]
n’a pas de sens :
s = "3000"
x = int(s)
print(s[0])
print(x[0])
print(x[0])
TypeError: 'int' object is not subscriptable
Le code de l’implémentation en C de la conversion semble se trouver ici, cf. la fonction PyLong_FromString
. La fonction est particulièrement complexe (mais elle convertit aussi depuis des bases autres que 10).
Chaînes autorisées¶
Pour qu’un appel str(s)
convertisse la chaîne s
en entier encore faut-il que la chaîne fournie représente un entier :
x = int("3.14")
print(x)
x = int("3.14")
ValueError: invalid literal for int() with base 10: '3.14'
La documentation indique que la chaîne doit être un entier littéral, ce qui d’ailleurs, n’est pas tout à fait vrai :
x = int("0042")
print(x)
42
alors que 0042
n’est pas un littéral entier valide :
x = 0042
print(x)
x = 0042
^
SyntaxError: invalid token
Conversion d’une chaîne en flottant¶
On peut avoir besoin de convertir une chaîne représentant un nombre décimal « à virgule » et dont on a besoin de connaître la valeur en tant que nombre, par exemple pour faire une opération. Typiquement, on a du texte comme ci-dessous
Dollar:0.83€
Livre:1.16€
Rouble:0.011€
donnant, entre autres, le cours du dollar en euro et qu’on cherche à savoir combien d’euros coûtent 42 dollars. Pour cela, on va capturer, par un moyen ou par un autre et que je ne détaille pas ici, la chaîne "0.83"
. Une fois ceci fait, voici comment on en récupère la valeur numérique :
1 2 3 4 | taux="0.83"
valeur = float(taux)
n=42
print(n, "dollars valent", n*valeur, "euros")
|
5 | 42 dollars valent 34.86 euros
|
- Ligne 1 :
taux
est une chaîne - Ligne 2 :
valeur
est la valeur flottante du nombre que la chaînetaux
représente. - Lignes 4 et 5: dès lors que
valeur
est un nombre, on peut faire avec ce nombre des opérations numériques, par exemple un produit ce qui permet d’effectuer le calcul du change de 42 €.
Valeur d’un entier donné en base autre que 10¶
On a vu que int
peut convertir une chaîne de chiffres décimaux en l’entier correspondant :
1 2 | x = 10 * int("42") + 1
print(x)
|
3 | 421
|
En réalité, il est possible de convertir un entier représenté en n’importe quelle base allant de 2 à 36, il suffit de le préciser dans l’appel à int
:
1 2 3 4 5 | x = int("101010", base=2)
print(x)
x = int("AC", base=13)
print(x)
|
6 7 | 42
142
|
Différence entre les fonctions str
et repr
¶
Les deux fonctions standard str
et repr
s’appliquent à n’importe quel objet Python et renvoient toutes les deux une chaîne qui est censée représenter l’objet en question. Un appel de str
sur un objet x
renvoie une chaîne de caractères qui est censée interpréter x
de façon informelle comme dit la documentation officielle. D’un autre côté, repr(x)
renvoie une représentation qui est, en principe, une expression Python valide et qui s’évalue en l’objet x
.
Les objets Fraction montrent bien la différence entre les deux. Python dispose d’un module standard appelé fractions
qui permet d’utiliser des fractions de nombres entiers. Une fraction est définie par une classe Fraction, par exemple la fraction \(\ds\frac{22}{7}\) est définie de la manière suivante :
from fractions import Fraction
f = Fraction(22, 7)
Pour afficher cette fraction, il serait naturel de lire 22/7
et c’est justement ainsi que cet affichage est codé en interne dans le module fractions :
from fractions import Fraction
f = Fraction(22, 7)
print(f)
22/7
Par construction, print(f)
affiche exactement la chaîne str(f)
et donc ici, cette chaîne se traduit par la chaîne littérale "22/7"
.
Maintenant, que vaut repr(f)
? Cela ne peut pas être la même chose car l’expression 22/7
n’est pas égale (en Python) à la fraction \(\ds\frac{22}{7}\) puisque 22/7
est un nombre flottant que Python ne connaît en plus qu’approximativement :
from fractions import Fraction
f = Fraction(22, 7)
print(f == 22/7)
False
Regardons ce que vaut repr(f)
:
from fractions import Fraction
f = Fraction(22, 7)
print(repr(f))
Fraction(22, 7)
On voit que repr(f) == s
où s := 'Fraction(22, 7)'
. Et en effet, la valeur de f
est le résultat de l’évaluation de l’expression entre les apostrophes, à savoir Fraction(22, 7).
Un autre exemple qui peut aider à faire comprendre la nuance est de considérer comment sont affichés les tableaux sous Numpy (qui est une bibliothèque Python massivement utilisée en apprentissage automatique). Observer le code suivant :
import numpy as np
z=np.zeros(5)
print(z)
print(repr(z))
[0. 0. 0. 0. 0.]
array([0., 0., 0., 0., 0.])
- Lignes 5 et 7 : un tableau Numpy est affiché en donnant la liste de ses éléments, sans virgule séparatrice.
- Lignes 6 et 8 :
repr(z)
affiche du code Python exécutable et qui renvoie un objet ayant même valeur quez
:
import numpy as np
from numpy import array
z=np.zeros(5)
zz = array([0., 0., 0., 0., 0.])
print(np.array_equal(z, zz))
True
Modifier la terminaison d’affichage par défaut¶
Par défaut, toute instruction d’affichage avec la fonction print
se termine par un saut de ligne. La fonction print
possède une « option » modifiant ce comportement par défaut en faisant en sorte que l’affichage soit terminé par une certaine suite de caractères décidée par le programmeur. Cette option consiste à passer un argument à la fonction print
, nommé end
et que le programmeur affecte au type de terminaison choisie.
Par exemple, supposons que l’on souhaite qu’un affichage soit terminé par deux points d’interrogation :
1 | print("lundi", "mardi", end = "??")
|
2 | lundi mardi??
|
- Ligne 1 :
print
a reçu trois arguments. Le dernier est un argument dit nommé : ici, c’est comme si on affectait une variable interne à la fonctionprint
, la variableend
. Le fait d’affecterend
dans l’appel deprint
modifie la terminaison d’affichage : les chaînes lundi et mardi sont affichées, séparées par un espace (comme d’habitude) et, immédiatement après, le contenu de la chaîneend
est affiché. On notera l’absence d’espace entremardi
et??
. - Les deux points d’interrogation ont été placés à la fin de l’affichage grâce à l’option
end
fournie àprint
. Toutefois, (rare) l’affichage dans certaines consoles pourra se comporter légèrement différemment.
Attention au comportement suivant :
1 2 3 4 | print("lundi", "mardi", end = "??")
print("mercredi")
print("jeudi")
|
5 6 | lundi mardi??mercredi
jeudi
|
- Ligne 1 : comme
end
n’a plus sa valeur par défaut, l’affichage n’est pas terminé par un saut de ligne - Ligne 3 : l’affichage est effectué immédiatement après l’affichage provoqué par la ligne 1, en particulier sans rajout de saut de ligne au précédent affichage. En revanche, à la fin de l’affichage mercredi,
print
rajoute un saut de ligne (c’est le comportement par défaut deprint
). - Ligne 4 : le mot est placé seul sur la ligne à cause du saut de ligne par défaut placé par le
print
à la ligne 3.
Modifier le séparateur par défaut de print
¶
Par défaut, lorsque print
reçoit plusieurs arguments, les affichages correspondants sont séparés par un espace et un seul. On peut modifier ce comportement par défaut en utilisant un argument nommé sep
et lui affecter le séparateur que l’on souhaite, par exemple "..."
si on veut séparer chaque affichage par trois points successifs :
1 | print("lundi", "mardi", "mercredi", sep = "...")
|
2 | lundi...mardi...mercredi
|
- Ligne 1 : l’argument nommé
sep
doit apparaître après la liste des chaînes à afficher.
L’affichage par défaut correspond à l’argument nommé sep = " "
autrement dit print("lundi", "mardi")
et print("lundi", "mardi", sep = " ")
sont équivalents :
print("lundi", "mardi")
print("lundi", "mardi", sep = " ")
lundi mardi
lundi mardi
Il est possible de cumuler la modification du séparateurs sep
et de la terminaison de ligne end
.
print("lundi", "mercredi", sep = "...", end = "???????")
m = "mardi"
print("lundi", m, "mercredi", sep = "...")
lundi...mercredi???????lundi...mardi...mercredi
Afficher plusieurs objets sans séparation¶
On souhaite afficher des objets, sans qu’il n’y ait d’espace entre eux à l’affichage, par exemple :
LundiMardiMercredi
Il y a deux façons d’y parvenir avec la fonction print
. Soit on modifie le séparateur par défaut, sep
, de la fonction print
en le plaçant à une chaîne vide, soit on fait de même mais avec le séparateur end
de terminaison de ligne :
print("Lundi", "Mardi", "Mercredi", sep="")
print("Lundi", end="")
print("Mardi", end="")
print("Mercredi")
LundiMardiMercredi
LundiMardiMercredi
Affichage parfait sur une même ligne et boucle for
¶
Ce paragraphe s’intéresse à une question très marginale. À examiner en seconde lecture.
Soit à réaliser avec une boucle for
l’affichage exact suivant :
0 1 2 3 4 5 6 7 8 9
Un espace doit figurer uniquement entre deux chiffres successifs mais pas en fin de ligne.
Le code suivant semble réaliser l’affichage demandé :
for i in range(10):
print(i, end = ' ')
0 1 2 3 4 5 6 7 8 9
Même si ce n’est pas visible, l’affichage n’est pas parfaitement conforme puisque lorsque i
vaut 9
dans la boucle for
, 9
est affiché suivi d’un espace alors qu’un espace est censé séparer un entier de son suivant dans la ligne (9 est le dernier entier de la ligne). On peut d’ailleurs le voir si on ajoute un affichage arbitraire :
for i in range(10):
print(i, end = ' ')
print("XXXXX")
0 1 2 3 4 5 6 7 8 9 XXXXX
on voit qu’avant le premier X
affiché, il y a un espace.
Pour obtenir un affichage parfaitement conforme, il faudrait interrompre la boucle juste avant la dernière étape puis afficher le dernier élément, non suivi d’un espace :
for i in range(9):
print(i, end = ' ')
print(9)
print("XXXXXX")
0 1 2 3 4 5 6 7 8 9
XXXXXX
Une autre solution est possible, voire préférable serait d’utiliser la méthode join
:
print(" ".join(str(i) for i in range(10)))
print("XXXXXX")
0 1 2 3 4 5 6 7 8 9
XXXXXX
Afficher sur la sortie d’erreurs standard¶
Quand on affiche un message, il apparaît, par défaut, sur ce qu’on appelle la sortie standard, désignée en Python par stdout
. En pratique, la sortie standard est une zone de texte spécifique : une console par exemple, l’output d’une cellule Jupyter, etc. Mais parfois, on ne veut pas, que certains messages apparaissent (par exemple des diagnostics, des erreurs d’exécution) et dans ce cas, il existe une possibilité de rediriger les messages de ce type vers une autre « zone » qu’on appelle l”erreur standard désignée sous le terme de stderr
.
Pour accéder à l’erreur standard, on utilise le module sys
:
1 2 3 4 | import sys
print(42)
print(2038, file=sys.stderr)
|
5 6 | 42
2038
|
On constate que les deux messages sont visibles dans la console alors que le 2e était pourtant dirigé vers l’erreur standard. C’est que, par défaut, les affichages sur la sortie standard et l’erreur standard, sont confondus.
L’usage de stderr est intéressant en cas de redirection, en permettant de distinguer les messages d’erreurs de la sortie « normale » :
main.py
1 2 3 4 | import sys
print(42)
print(2038, file=sys.stderr)
|
5 6 | $ python3.4 main.py > mon_fichier.txt
2038
|
et dans ce cas, le contenu de mon_fichier.txt
est :
1 | 42
|
Afficher sous Jupyter Notebook ou dans une console Python¶
Comment est réalisé l’affichage de calculs dans une feuille Jupyter Notebook ou une console Python ? Dans une feuille Jupyter Notebook, soit la cellule de code suivante, suivie de l’affichage produit dans une cellule d”output par l’exécution de la cellule :
1 2 3 | 1 + 1
print(2 + 2)
3 + 3
|
4 5 | 4
6
|
- Ligne 1 : la valeur de l’expression n’est pas affichée dans la cellule d”output, faute d’appel à la fonction
print
- Lignes 2 et 4 : puisque la fonction
print
est utilisée, un affichage est visible. - Ligne 3 et 5 : malgré l’absence de
print
, il y a eu un affichage : en effet la dernière instruction de la cellule est une expression (3 + 3
) et dans ce cas, sa valeur est affichée.
En revanche, la cellule suivante
1 + 1
3 + 3
x = 42
ne produira aucun affichage. En effet, la dernière instruction n’est pas une expression.
Il reste le cas particulier où l’expression en dernière ligne vaut None
: dans ce cas, rien n’est affiché :
1 2 3 | L = [40, 41]
print("append : ", L.append(42))
L.append(43)
|
4 | append : None
|
- L’affichage visible provient de la ligne 2 et de l’appel à la fonction
print
: l’appelL.append(42))
vautNone
et c’est ce qui est affiché - Comme indiqué précedemment, l’expression
L.append(43)
vaut toujoursNone
. Pourtant, cette expression, bien que dernière dans la cellule, n’affiche pasNone
. C’est normal, c’est l’effet recherché par le fonctionnement d’une cellule Jupyter Notebook.
Par ailleurs, l’affichage que peut produire l’expression, disons expr
, en dernière ligne de la cellule, affiche en fait repr(expr)
et non pas l’affichage habituel. On le voit bien avec une chaîne de caractères :
1 2 3 4 5 6 | c = "Orange"
print(c)
print(repr(c))
"Orange"
|
7 8 9 | Orange
'Orange'
'Orange'
|
La dernière ligne (ligne 9) provenant de l’expression ligne 6 montre le mot entouré d’apostrophes : c’est exactement l’affichage de repr(c)
, cf. lignes 4 et 8.
Le comportement de l’affichage lorsque Python est utilisé en mode interactif (une « console avec un prompt Python ») est très semblable :
1 2 3 4 5 | >>> print("Orange")
Orange
>>> "Orange"
'Orange'
>>>
|
Décompactage des arguments de la fonction print
¶
Le décompactage des arguments appliqué à la fonction print
permet d’obtenir assez simplement des effets d’affichage (le décompactage est le résultat de l’usage de la syntaxe *
devant un itérable, voir ci-dessous l’exemple).
Par exemple, on dispose d’une liste L
d’entiers et on veut afficher ces entiers juste séparés par un espace :
L = [65, 31, 9, 32, 81, 82, 46, 12]
print(*L)
65 31 9 32 81 82 46 12
En effet, par définition même de la syntaxe de décompactage, l’appel print(*L)
est équivalent à :
print(65, 31, 9, 32, 81, 82, 46, 12)
et on sait que, dans ce cas (le cas par défaut), les arguments de la fonctions print
sont séparés par un espace.
En utilisant les argument nommés de la fonction print
, l’affichage peut être enrichi :
L = [65, 31, 9, 32, 81, 82, 46, 12]
print(*L, sep=', ')
65, 31, 9, 32, 81, 82, 46, 12
La décompactage des arguments s’applique à tout itérable. Par exemple, aux chaînes de caractères, ce qui permet d’afficher facilement les lettres d’un mot :
print(*"ORANGE", sep='.')
O.R.A.N.G.E
Il s’applique aussi aux expressions génératrices, par exemple :
print(*(k for k in range(20) if k%3==0 and k%5!=0))
3 6 9 12 18
Vider le buffer¶
La sortie de print
est bufférisée, c’est-à-dire que le contenu de l’affichage est placé dans une mémoire-tampon et lorsque la mémoire-tampon est pleine ou lorsque les données sont construites, le buffer est vidé et les données sont envoyées dans la zone d’affichage, habituellement la sortie standard (stdout).
La présence de certains caractères vide le buffer, par exemple le caractère saut de ligne ('\n'
) à pour effet de vider le tampon ce qui provoque l’affichage.
Si une chaîne de caractères doit être affiché et qu’elle ne contient pas de saut de ligne, il peut y avoir un délai d’attente entre l’instruction print
et l’affichage réel, comme le montre le code ci-dessous :
1 2 3 4 5 | import time
for c in "Python"*3:
print(c, end='...')
time.sleep(0.5)
|
6 | P...y...t...h...o...n...P...y...t...h...o...n...P...y...t...h...o...n...
|
Chaque appel à sleep
temporise l’exécution pendant 1/2 seconde. Dans ce code, l’affichage (ligne 6) n’apparaît qu’au bout de 9 secondes, et il apparaît d’un seul coup. En effet, l’appel à la fonction print
ne contient pas de saut de ligne (puisque end
vaut autre chose, cf. ligne 4), donc le buffer est vidé lorsque le programme se termine.
Pour provoquer le vidage du buffer, on peut utiliser l’option flush=True
de la fonction print
:
1 2 3 4 5 | import time
for c in "Python"*3:
print(c, end='...', flush=True)
time.sleep(0.5)
|
6 | P...y...t...h...o...n...P...y...t...h...o...n...P...y...t...h...o...n...
|
Cette fois l’affichage apparaît progressivement, chaque caractère attend 1/2 seconde avant d’être affiché.
Chaîne analogue à un fichier¶
On aimerait parfois qu’un code qui capture des données dans un fichier texte soit encore applicable à un code où les données seraient dans une chaîne au lieu d’être dans un fichier.
Par exemple, soit le fichier planetes.txt
Mars
Jupiter
Uranus
Neptune
et le code suivant qui affiche le contenu du fichier planetes.txt
:
1 2 3 | fichier = open("planetes.txt")
contenu = fichier.read()
print(contenu)
|
Le contenu du fichier planetes.txt
est représenté par la chaîne "Mars\nJupiter\nUranus\nNeptune"
. On souhaiterait que la partie suivante du code précédent :
1 2 | contenu = fichier.read()
print(contenu)
|
soit encore applicable si on dispose d’une chaîne au lieu du fichier planetes.txt
. La solution est donnée par la fonction io.StringIO
du module standard io
:
1 2 3 4 5 6 7 | import io
s = "Mars\nJupiter\nUranus\nNeptune"
fichier = io.StringIO(s)
contenu = fichier.read()
print(contenu)
|
8 9 10 11 | Mars
Jupiter
Uranus
Neptune
|
- Ligne 5 : la fonction
io.StringIO
renvoie un objet de typeio.StringIO
et qui admet les méthodes de fichier. - Ligne 6 : on peut lire
fichier
(qui n’est pas un objet de type file) comme un objet de type file, en particulier avec la méthode read.
Le cas de l’entrée standard¶
De la même façon, on peut émuler l”entrée standard par une chaîne. Par exemple, voici un code qui effectue la somme de deux entiers donnés sur l’entrée standard :
somme_readlines.py
1 2 3 4 5 6 | import sys
stdin = sys.stdin
L = stdin.readlines()
x = L[0]
y = L[1]
print(int(x)+int(y))
|
7 8 9 | 42
10
52
|
Pour transmettre les nombres:
- soit on appuie sur la touche Entrée après chaque nombre et, à la fin, on transmet via le clavier le caractère de fin de fichier EOF (
Ctrl + D
sous Linux) - (le plus commode) soit on place les deux nombres dans un fichier
nombres.txt
(un nombre par ligne et sans saut de ligne final) et le code Python (somme_readlines.py
) capture les deux entiers par redirection en lançant en ligne de commande :
$ python3 somme.py < nombres.txt
Voici maintenant un code qui conserve l’essentiel de somme_readlines.py
mais en lisant les entrées dans une chaîne :
1 2 3 4 5 6 7 8 9 | import io
s = "42\n10\n"
stdin = io.StringIO(s)
L = stdin.readlines()
x = L[0]
y = L[1]
print(int(x)+int(y))
|
10 | 52
|
- Lignes 6-9 : la partie lecture et calcul du code de
somme_readlines.py
est préservée.
Afficher « dans » une chaîne¶
La sortie standard (là où on affiche communément) est un fichier comme un autre. On y a accède via sys.stdout
et ce fichier possède une méthode write
permettant d’afficher (c’est plus ou moins équivalent à print
). Voici un exemple :
import sys
cible = sys.stdout
message1 = "Mars\nJupiter\n"
cible.write(message1)
message2 = "Uranus\nNeptune\n"
cible.write(message2)
qui produit, en principe dans une console ou une zone de sortie textuelle, l’affichage suivant
1 2 3 4 | Mars
Jupiter
Uranus
Neptune
|
On peut parfois souhaiter que tous les affichages qu’un code effectue soient envoyés dans une chaîne au lieu de la sortie standard sans pour autant modifier profondément le code. C’est possible en utilisant le module standard stringIO
. Voici un exemple équivalent au précédent :
1 2 3 4 5 6 7 8 9 10 | import io
cible = io.StringIO()
message1 = "Mars\nJupiter\n"
cible.write(message1)
message2 = "Uranus\nNeptune\n"
cible.write(message2)
print(cible.getvalue())
|
11 12 13 14 | Mars
Jupiter
Uranus
Neptune
|
- Ligne 2 : la chaîne dans laquelle les messages ultérieurs vont être « affichés ».
- Lignes 5 et 8 : envoie des messages dans la chaîne avec la méthode
write
. - Ligne 10 : pour récupérer le contenu de la chaîne de type
StringIO
, on appelle sa méthodegetvalue
ce qui renvoie une chaîne habituelle et que l’on peut afficher. - Ligne 11-14 : on récupère bien le contenu envoyé dans la chaîne et comme avec le code précédent.
Utilisation de la fonction print
¶
Il est également possible d’envoyer l’affichage dans une chaîne StringIO
au moyen de la fonction print
. En effet, la fonction print
dispose d’un argument nommé file
qui par défaut pointe vers la sortie standard. On peut passer une autre valeur, par exemple une chaîne StringIO
, exactement comme à l’exemple précédent. On peut en plus utiliser les autres arguments nommés sep
ou end
pour formater l’affichage. Voici un exemple :
1 2 3 4 | import io
cible = io.StringIO()
print("Mars", "Jupiter", "Uranus", "Neptune", sep='\n', end='', file=cible)
|
Ce code n’affiche rien car l’affichage a été détournée vers la chaîne cible. Dans cible
, les objets à afficher sont séparés par des sauts de ligne, cf. sep='\n'
. Noter que pour éviter un saut de ligne non désiré, la fin de ligne par défaut (qui est un saut de ligne) a été écrasée par end=''
.
Il est bien sûr possible d’afficher le contenu de cible
en récupérant son contenu via la méthode getvalue
:
import io
cible = io.StringIO()
print("Mars", "Jupiter", "Uranus", "Neptune", sep='\n', end='', file=cible)
print(cible.getvalue())
Mars
Jupiter
Uranus
Neptune