2012-06-08 8 views
5

Mientras trabajaba en este ejercicio me encontré con un problema.En Python, ¿cómo puedo abrir un archivo y leerlo en una línea, y aún así poder cerrar el archivo después?

from sys import argv 
from os.path import exists 

script, from_file, to_file = argv 
print "Copying from %s to %s" % (from_file, to_file) 

# we could do these two on one line too, how? 
input = open(from_file) 
indata = input.read() 

print "The input file is %d bytes long" % len(indata) 
print "Does the output file exist? %r" % exists(to_file) 
print "Ready, hit RETURN to continue, CTRL-C to abort." 

raw_input() 

output = open(to_file, 'w') 
output.write(indata) 
print "Alright, all done." 
output.close() 
input.close() 

La línea # we could do these two on one line too, how? es lo que me está confundiendo. La única respuesta que podía venir fue:

indata = open(from_file).read() 

Esto lleva a cabo de la manera que quería, pero me obliga a retirar:

input.close() 

que ya no existe la variable de entrada. ¿Cómo puedo, entonces, realizar esta operación cercana?

¿Cómo solucionaría esto?

+0

gracias a todos. Me siento mejor ahora. @Paul D. Waite Gracias por editar mi pregunta. Está mucho más claro ahora. – yoonsi

+0

¡De nada!A menudo es más fácil para otra persona ver cuál es el quid de la cuestión. –

Respuesta

14

La mejor forma de trabajar con los recursos en Python es usar context managers:

with open(infile) as fp: 
    indata = fp.read() 

La declaración with se encarga de cerrar el recurso y la limpieza.

Usted podría escribir que en una sola línea si desea: mal estilo sin embargo

with open(infile) as fp: indata = fp.read() 

, esto se considera en Python.

También puede abrir múltiples archivos en un bloque with:

with open(input, 'r') as infile, open(output, 'w') as outfile: 
    # use infile, outfile 

divertido lo suficiente, me preguntó exactly the same question atrás cuando empecé a aprender Python.

+0

El buen estilo aconseja, pero no responde la pregunta, ya que no está en una línea. – Junuxx

+0

@ thg435, ¡No es una forma estándar! Just file-object implementa la interfaz Context Manager. – astynax

+0

@astynax: sí, "preffered" suena mejor. – georg

0

El archivo se cerrará de forma automática y segura cuando se complete la secuencia de comandos.

+3

Probablemente. Pero es una mala idea acostumbrarse a confiar en esto, porque entonces serás inútil para programas más grandes que tienen que abrir una gran cantidad de archivos a lo largo del tiempo. El recuento * puede * salvarlo, pero luego está vinculado a CPython y no puede, por ejemplo, hacer que el programa sea 3 veces más rápido ejecutándolo en PyPy porque PyPy tiene un GC mejor. Solo acostúmbrese a liberar recursos tan pronto como sea razonable. Realmente no es difícil. -1 – delnan

+0

E incluso si el refcounting lo salva, obtendrá un 'ResourceWarning' en Python 3.2 para cada archivo que se cierra automáticamente. –

2
with open(from_file, 'r') as f: 
    indata = f.read() 

# outputs True 
print f.closed 
2

Usted debe pensar en esto como un ejercicio para entender que input es sólo un nombre para lo open rendimientos en lugar de como un consejo que debe a haces de la manera más corta.

Como mencionan otras respuestas, en este caso particular, el problema que ha identificado correctamente no es un problema importante: el script se cierra bastante rápido, por lo que cualquier archivo que abra se cerrará con bastante rapidez. Pero ese no es siempre el caso, y la forma habitual de garantizar que un archivo se cerrará una vez que haya terminado con él es usar una declaración with, de la cual se enterará cuando continúe con Python.

0

El siguiente código de Python logrará su objetivo.

from contextlib import nested 

with nested(open('input.txt', 'r'), open('output.txt', 'w')) as inp, out: 
    indata = inp.read() 
    ... 
    out.write(out_data) 
+2

'contextlib.nested' no tiene sentido en las versiones más recientes de Python. – delnan

+3

@delnan Peor que eso 'contextlib.nested()' should ** never ** se debe usar para abrir dos archivos: si hay un error abriendo el segundo, el primero no se cerrará. Este es un error documentado y es una de las razones por las que está obsoleto a favor de la nueva sintaxis 'with'. –

+0

@Lattyware, gracias por la información. Lo tendré en mente. – astynax

0

sólo tiene que utilizar un punto y coma en medio de su línea de código existente es decir

in_file = open(from_file); indata = in_file.read() 

Creo que la suya es lo que buscabas ..

Cuestiones relacionadas