web-dev-qa-db-fra.com

Bonne façon d'écrire la ligne dans le fichier?

J'ai l'habitude de faire print >>f, "hi there"

Cependant, il semble que print >> soit obsolète. Quelle est la manière recommandée de faire la ligne ci-dessus?

Mise à jour: Concernant toutes ces réponses avec "\n"... est-ce universel ou spécifique à Unix? IE, devrais-je faire "\r\n" sous Windows?

945
Yaroslav Bulatov

Cela devrait être aussi simple que:

_with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello\n')
_

De la documentation:

N'utilisez pas _os.linesep_ comme terminateur de ligne lors de l'écriture de fichiers ouverts en mode texte (par défaut); utilisez un seul '\ n' à la place, sur toutes les plateformes.

Quelques lectures utiles:

960
Johnsyweb

Vous devez utiliser la fonction print() disponible depuis Python 2.6+.

from __future__ import print_function  # Only needed for Python 2
print("hi there", file=f)

Pour Python 3, vous n'avez pas besoin de import, car la fonction print() est la valeur par défaut.

L'alternative serait d'utiliser:

f = open('myfile', 'w')
f.write('hi there\n')  # python will convert \n to os.linesep
f.close()  # you can omit in most cases as the destructor will call it

Citant de documentation Python concernant les nouvelles lignes:

En sortie, si newline est None, tous les caractères '\n' écrits sont traduits dans le séparateur de ligne par défaut du système, os.linesep. Si newline est '', aucune traduction n'a lieu. Si newline est l'une des autres valeurs légales, tous les caractères '\n' écrits sont traduits dans la chaîne donnée.

941
sorin

Les python docs recommandent cette façon:

with open('file_to_write', 'w') as f:
    f.write('file contents')

Donc, c'est comme ça que je le fais d'habitude :)

Déclaration de docs.python.org :

Il est recommandé d’utiliser le mot-clé 'avec' lorsqu’il s’agit d’objets fichier. Cela présente l'avantage que le fichier est correctement fermé à la fin de la suite, même si une exception est déclenchée. C'est aussi beaucoup plus court que d'écrire des blocs try-finally équivalents.

106
j7nn7k

Concernant os.linesep:

Voici une session d'interprète Python 2.7.1 exacte non modifiée sur Windows:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.linesep
'\r\n'
>>> f = open('myfile','w')
>>> f.write('hi there\n')
>>> f.write('hi there' + os.linesep) # same result as previous line ?????????
>>> f.close()
>>> open('myfile', 'rb').read()
'hi there\r\nhi there\r\r\n'
>>>

Sous Windows:

Comme prévu, os.linesep ne donne PAS le même résultat que '\n'. Il n'y a aucun moyen que cela puisse produire le même résultat. 'hi there' + os.linesep est équivalent à 'hi there\r\n', ce qui est NOT équivalent à 'hi there\n'.

C'est aussi simple que cela: utilisez \n qui sera traduit automatiquement en os.linesep. Et cela a été aussi simple depuis le premier port de Python vers Windows.

Il est inutile d'utiliser os.linesep sur des systèmes autres que Windows et les résultats obtenus sont erronés sous Windows.

NE PAS UTILISER os.linesep!

85
John Machin

Je ne pense pas qu'il existe un "correct" chemin.

J'utiliserais:

with open ('myfile', 'a') as f: f.write ('hi there\n')

En mémoire Tim Toady .

53
Hyperboreus

Dans Python 3, il s'agit d'une fonction, mais dans Python 2, vous pouvez l'ajouter en haut du fichier source:

from __future__ import print_function

Alors vous faites

print("hi there", file=f)
21
Keith

Si vous écrivez beaucoup de données et que la vitesse vous préoccupe, vous devriez probablement utiliser f.write(...). J'ai fait une comparaison rapide de la vitesse et elle était considérablement plus rapide que print(..., file=f) lors de l'exécution d'un grand nombre d'écritures.

import time    

start = start = time.time()
with open("test.txt", 'w') as f:
    for i in range(10000000):
        # print('This is a speed test', file=f)
        # f.write('This is a speed test\n')
end = time.time()
print(end - start)

En moyenne, write a terminé en 2,45 secondes sur ma machine, alors que print a pris environ 4 fois plus de temps (9,76s). Cela étant dit, dans la plupart des scénarios réels, cela ne posera pas de problème.

Si vous choisissez d'utiliser print(..., file=f), vous constaterez probablement que vous souhaitez supprimer la nouvelle ligne de temps à autre ou la remplacer par quelque chose d'autre. Cela peut être fait en définissant le paramètre facultatif end, par exemple;

with open("test", 'w') as f:
    print('Foo1,', file=f, end='')
    print('Foo2,', file=f, end='')
    print('Foo3', file=f)

Quelle que soit la méthode choisie, je vous suggérerais d'utiliser with, car cela rend le code beaucoup plus facile à lire.

Mise à jour : cette différence de performances s'explique par le fait que write est fortement mis en mémoire tampon et revient avant toute écriture sur le disque (voir cette réponse ), alors que print (probablement) utilise la mise en mémoire tampon des lignes. Un test simple consiste à vérifier également les performances pour les écritures longues, où les inconvénients (en termes de vitesse) de la mise en mémoire tampon des lignes seraient moins prononcés.

start = start = time.time()
long_line = 'This is a speed test' * 100
with open("test.txt", 'w') as f:
    for i in range(1000000):
        # print(long_line, file=f)
        # f.write(long_line + '\n')
end = time.time()

print(end - start, "s")

La différence de performance devient maintenant beaucoup moins prononcée, avec un temps moyen de 2,20 secondes pour write et de 3,10 secondes pour print. Si vous avez besoin de concaténer un tas de chaînes pour obtenir cette performance de ligne loooong en souffrira, les cas d'utilisation où print serait plus efficace seraient un peu rares.

16
Robin Keskisarkka

Depuis la version 3.5, vous pouvez également utiliser pathlib à cette fin:

Path.write_text (données, encodage = Aucun, erreurs = Aucun)

Ouvrez le fichier pointé en mode texte, écrivez-lui des données et fermez le fichier:

import pathlib

pathlib.Path('textfile.txt').write_text('content')
9
johnson

Lorsque vous avez dit Ligne, cela signifie des caractères sérialisés qui se terminent par des caractères '\ n'. La ligne devrait être la dernière à un moment donné, nous devrions donc considérer "\ n" à la fin de chaque ligne. Voici la solution:

with open('YOURFILE.txt', 'a') as the_file:
    the_file.write('Hello')

après chaque écriture, le curseur passe à la nouvelle ligne. Si vous souhaitez utiliser le mode "w", vous devez ajouter les caractères "\ n" à la fin de la fonction write ():

the_file.write('Hello'+'\n')
4
Reza Tanzifi

On peut aussi utiliser le module io comme dans:

import io
my_string = "hi there"

with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
    f.write(my_string)
3
kmario23

Quand j'ai besoin d'écrire beaucoup de nouvelles lignes, je définis un lambda qui utilise une fonction print:

out = open(file_name, 'w')
fwl = lambda *x, **y: print(*x, **y, file=out) # FileWriteLine
fwl('Hi')

Cette approche présente l'avantage de pouvoir utiliser toutes les fonctionnalités disponibles avec la fonction print.

Mise à jour: Comme mentionné par Georgy dans la section des commentaires, il est possible d'améliorer cette idée avec la variable partial une fonction:

from functools import partial
fwl = partial(print, file=out)

IMHO, c'est une approche plus fonctionnelle et moins cryptée.

0
MxNx

Vous pouvez également essayer filewriter

pip install filewriter

from filewriter import Writer

Writer(filename='my_file', ext='txt') << ["row 1 hi there", "row 2"]

Écrit dans my_file.txt

Prend un objet iterable ou un objet avec le support __str__.

0
Emin Buğra Saral