91 votes

Ajouter une ligne à un fichier existant en Python

J'ai besoin d'ajouter une seule ligne à la première ligne d'un fichier texte et il semble que les seules options disponibles sont plus de lignes de code que ce que j'attendrais de python. Quelque chose comme ceci :

f = open('filename','r')
temp = f.read()
f.close()

f = open('filename', 'w')
f.write("#testfirstline")

f.write(temp)
f.close()

N'y a-t-il pas de solution plus simple ? En outre, je vois plus souvent cet exemple à deux poignées que l'ouverture d'une seule poignée pour la lecture et l'écriture ("r+") - pourquoi ?

1 votes

(A noter : il est probablement préférable de lire le fichier ligne par ligne et d'écrire dans un fichier temporaire. Lorsque vous avez terminé, supprimez le fichier original et remplacez-le par le fichier temporaire).

114voto

Nicholas Knight Points 9293

Python facilite beaucoup de choses et contient des librairies et des enveloppes pour de nombreuses opérations courantes, mais le but n'est pas de cacher des vérités fondamentales.

La vérité fondamentale que vous rencontrez ici est que vous ne pouvez généralement pas ajouter des données à une structure plate existante sans réécrire l'ensemble de la structure. Cela est vrai quel que soit le langage utilisé.

Il existe des moyens de sauvegarder un filehandle ou de rendre votre code moins lisible, dont beaucoup sont fournis dans d'autres réponses, mais aucun ne change l'opération fondamentale : Vous devez lire le fichier existant, puis écrire les données que vous souhaitez ajouter, suivies des données existantes que vous avez lues.

Vous pouvez vous épargner le filehandle, mais ne cherchez pas à faire tenir cette opération en aussi peu de lignes de code que possible. En fait, ne cherchez jamais à réduire le nombre de lignes de code : c'est de l'obscurcissement, pas de la programmation.

44 votes

"Ne jamais chercher à avoir le moins de lignes de code possible - c'est de l'obscurcissement, pas de la programmation" - Cacher le temps qu'il faut pour exécuter une fonction n'est pas de l'obscurcissement, c'est de l'abstraction. Si le but du code était de prendre un temps proportionnel à la lecture et à l'exécution, le code aurait une structure totalement différente de celle qu'il a en réalité.

2 votes

"Vous devez lire le fichier existant, puis écrire les données que vous voulez ajouter, suivies des données existantes que vous avez lues" - ce n'est pas vraiment vrai, il peut être beaucoup plus efficace en termes de mémoire de fragmenter et d'entrelacer les opérations de lecture et d'écriture de sorte que le contenu complet du fichier n'ait jamais besoin de résider en mémoire en une seule fois. Le traitement des détails de cette question constituerait en fait une excellente bibliothèque.

98voto

Karl Knechtel Points 24349

Je m'en tiendrais à des lectures et des écritures séparées, mais nous pouvons certainement les exprimer de manière plus concise :

Python2 :

with file('filename', 'r') as original: data = original.read()
with file('filename', 'w') as modified: modified.write("new first line\n" + data)

Python3 :

with open('filename', 'r') as original: data = original.read()
with open('filename', 'w') as modified: modified.write("new first line\n" + data)

Note : la fonction file() n'est pas disponible dans python3.

1 votes

Veuillez noter que le file() -n'est pas disponible dans Python 3, seulement dans la version 2. Il suffit de la remplacer par open() dans Python 3.

8 votes

En fait, vous ne devriez pas non plus utiliser la fonction file dans Python 2. Vous devez toujours ouvrir des fichiers à l'aide de la fonction open() dans l'une ou l'autre des deux versions de Python. La fonction file n'existe que pour des raisons historiques.

0 votes

@HenrySchreiner à l'époque, j'avais le sentiment que file était plus intuitive, indépendamment du consensus de la communauté et des lignes directrices communes en matière de style. Mais lorsque la version 3.x est arrivée (et j'ai été un adoptant assez enthousiaste FWIW), je n'ai plus eu le choix :)

27voto

Morlock Points 1200

Autre approche :

with open("infile") as f1:
    with open("outfile", "w") as f2:
        f2.write("#test firstline")
        for line in f1:
            f2.write(line)

ou un one liner :

open("outfile", "w").write("#test firstline\n" + open("infile").read())

Merci de m'avoir donné l'occasion de réfléchir à ce problème :)

Santé

13voto

barti_ddu Points 5423
with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s)

3voto

infrared Points 1358

Cela permet d'économiser un appel d'écriture :

f.write('#testfirstline\n' + temp)

Lorsque vous utilisez "r+", vous devez rembobiner le fichier après l'avoir lu et avant de l'écrire.

2 votes

+1, bien que vous auriez pu économiser toute une ligne de code en faisant f.write('#testfirstline\n' + temp)

5 votes

Je recommande f.writelines(('#testfirstline\n',tmp)) . Ainsi, si temp est énorme, vous ne créez pas une autre chaîne énorme pour écrire tout cela. Ou alors, il suffit d'utiliser la ligne d'écriture supplémentaire comme dans l'OP...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X