Pregunta ¿Forma correcta de escribir línea a archivo?


Estoy acostumbrado a hacer print >>f, "hi there"

Sin embargo, parece que print >> está siendo desaprobado. ¿Cuál es la forma recomendada de hacer la línea de arriba?

Actualizar: En cuanto a todas esas respuestas con "\n"... es esto universal o específico de Unix? IE, debería estar haciendo "\r\n" en Windows?


773
2018-05-28 05:44


origen


Respuestas:


Esto debería ser tan simple como:

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

De la documentación:

No utilice os.linesep como un terminador de línea cuando se escriben archivos abiertos en modo texto (por defecto); use una sola '\ n' en su lugar, en todas las plataformas.

Algunas lecturas útiles:


694
2018-05-28 06:36



Deberías usar el print() función que está disponible desde Python 2.6+

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

Para Python 3 no necesita el import, desde el print() la función es la predeterminada.

La alternativa sería usar:

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

Citando de Documentación de Python con respecto a nuevas líneas

En salida, si newline es None, any '\n' los caracteres escritos se traducen al separador de línea predeterminado del sistema, os.linesep. Si es nueva línea '', no se lleva a cabo ninguna traducción. Si newline es cualquiera de los otros valores legales, cualquier '\n' los caracteres escritos se traducen a la cadena dada.


897
2018-05-28 05:48



los documentos de Python lo recomiendo de esta manera:

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

Así que esta es la forma en que generalmente lo hago :)

Declaración de docs.python.org:

Es una buena práctica usar el 'con' palabra clave cuando se trata de archivo   objetos. Esto tiene la ventaja de que el archivo se cierra correctamente después   su suite termina, incluso si se levanta una excepción en el camino. Es   también mucho más corto que escribir bloques equivalentes try-finally.


91
2017-10-13 09:37



En cuanto a os.linesep:

Aquí hay una sesión de intérprete de Python 2.7.1 exacta sin editar en 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'
>>>

En Windows:

Como se esperaba, os.linesep hace NO producir el mismo resultado que '\n'. No hay forma de que pueda producir el mismo resultado. 'hi there' + os.linesep es equivalente a 'hi there\r\n', cual es NO equivalente a 'hi there\n'.

Es así de simple: uso \n que se traducirá automáticamente a os.linesep. Y ha sido así de simple desde el primer puerto de Python en Windows.

No tiene sentido usar os.linesep en sistemas que no sean de Windows y produce resultados incorrectos en Windows.

NO UTILIZAR os.linesep!


80
2018-05-29 03:02



No creo que haya una manera "correcta".

Yo usaría:

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

En memoria Tim Toady.


46
2018-05-28 05:48



En Python 3 es una función, pero en Python 2 puede agregar esto a la parte superior del archivo fuente:

from __future__ import print_function

Entonces lo haces

print("hi there", file=f)

17
2018-05-28 05:49



Si está escribiendo una gran cantidad de datos y la velocidad es una preocupación, probablemente debería ir con f.write(...). Hice una comparación de velocidad rápida y fue considerablemente más rápido que print(..., file=f) cuando se realiza una gran cantidad de escrituras.

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)

De media write terminado en 2.45s en mi máquina, mientras que print tomó aproximadamente 4 veces más tiempo (9.76s). Dicho esto, en la mayoría de los escenarios del mundo real esto no será un problema.

Si eliges ir con print(..., file=f) probablemente descubras que querrás suprimir la nueva línea de vez en cuando, o reemplazarla por otra cosa. Esto puede hacerse configurando el opcional end parámetro, por ejemplo;

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

Cualquiera que sea la forma que elijas, te sugiero usar with ya que hace que el código sea mucho más fácil de leer.

Actualizar: Esta diferencia en el rendimiento se explica por el hecho de que write es altamente amortiguado y regresa antes de que ocurra cualquier escritura en el disco (ver esta respuesta), mientras que print (probablemente) utiliza el buffer de línea. Una prueba simple para esto sería verificar el rendimiento de las escrituras largas también, donde las desventajas (en términos de velocidad) para el almacenamiento en línea serían menos pronunciadas.

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 diferencia de rendimiento ahora se vuelve mucho menos pronunciada, con un tiempo promedio de 2.20s para write y 3.10s para print. Si necesita concatenar un montón de cadenas para obtener esta línea loooong, el rendimiento sufrirá, por lo que use-cases donde print Sería más eficiente son un poco raros.


14
2017-09-13 16:20