Pourquoi suis-je incapable d'utiliser une chaîne pour une nouvelle ligne dans write () mais je peux l'utiliser dans writelines ()?
L'idée est la suivante: si vous voulez écrire une seule chaîne, vous pouvez le faire avec write()
. Si vous avez une séquence de chaînes, vous pouvez toutes les écrire en utilisant writelines()
.
write(arg)
attend une chaîne comme argument et l'écrit dans le fichier. Si vous fournissez une liste de chaînes, cela lèvera une exception (au fait, montrez-nous les erreurs!).
writelines(arg)
attend un itérable comme argument (un objet itérable peut être un tuple, une liste, une chaîne ou un itérateur au sens le plus général). Chaque élément contenu dans l'itérateur doit être une chaîne. Un tuple de chaînes est ce que vous avez fourni, donc les choses ont fonctionné.
La nature de la ou des chaînes n'a pas d'importance pour les deux fonctions, c'est-à-dire qu'elles écrivent simplement dans le fichier tout ce que vous leur fournissez. La partie intéressante est qu'elle writelines()
n'ajoute pas de caractères de nouvelle ligne en soi, de sorte que le nom de la méthode peut en fait être assez déroutant. Il se comporte en fait comme une méthode imaginaire appelée write_all_of_these_strings(sequence)
.
Ce qui suit est une manière idiomatique en Python d'écrire une liste de chaînes dans un fichier tout en gardant chaque chaîne dans sa propre ligne:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.write('\n'.join(lines))
Cela prend soin de fermer le fichier pour vous. La construction '\n'.join(lines)
concatène (connecte) les chaînes de la liste lines
et utilise le caractère '\ n' comme colle. C'est plus efficace que d'utiliser l' +
opérateur.
À partir de la même lines
séquence, se terminant avec la même sortie, mais en utilisant writelines()
:
lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
f.writelines("%s\n" % l for l in lines)
Cela utilise une expression de générateur et crée dynamiquement des chaînes terminées par une nouvelle ligne. writelines()
itère sur cette séquence de chaînes et écrit chaque élément.
Edit: Un autre point dont vous devez être conscient:
write()
et readlines()
existait avant a writelines()
été introduit. writelines()
a été introduit plus tard en tant que contrepartie de readlines()
, afin que l'on puisse facilement écrire le contenu du fichier qui vient d'être lu via readlines()
:
outfile.writelines(infile.readlines())
Vraiment, c'est la principale raison pour laquelle writelines
a un nom si déroutant. Aussi, aujourd'hui, nous ne voulons plus vraiment utiliser cette méthode. readlines()
lit le fichier entier dans la mémoire de votre machine avant de writelines()
commencer à écrire les données. Tout d'abord, cela peut perdre du temps. Pourquoi ne pas commencer à écrire des parties de données tout en lisant d'autres parties? Mais, plus important encore, cette approche peut être très gourmande en mémoire. Dans un scénario extrême, où le fichier d'entrée est plus volumineux que la mémoire de votre machine, cette approche ne fonctionnera même pas. La solution à ce problème consiste à n'utiliser que des itérateurs. Un exemple de travail:
with open('inputfile') as infile:
with open('outputfile') as outfile:
for line in infile:
outfile.write(line)
Cela lit le fichier d'entrée ligne par ligne. Dès qu'une ligne est lue, cette ligne est écrite dans le fichier de sortie. En termes schématiques, il n'y a toujours qu'une seule ligne en mémoire (par rapport au contenu entier du fichier étant en mémoire dans le cas de l'approche readlines / writelines).
lines
n'est pas une chaîne dans votre exemple. C'est un tuple composé de six chaînes.