2012-01-24 40 views
10

Algunas veces, al usar ipython, puede presionar una excepción en una función que ha abierto un archivo en modo de escritura. Esto significa que la próxima vez que se ejecute la función se obtiene un error de valor,Cierre todos los archivos abiertos en ipython

ValueError: The file 'filename' is already opened. Please close it before reopening in write mode.

Sin embargo ya que la función largó, el identificador de archivo (que se creó dentro de la función) se pierde, por lo que no puede ser cerrado. La única forma redonda que parece ser la de cerrar la sesión ipython, momento en el que aparece el mensaje:

Closing remaining open files: filename... done

¿Hay una manera de instruir ipython para cerrar los archivos sin salir de la sesión?

+5

Usted debe tratar de utilizar siempre la declaración [ 'with'] (http://docs.python.org/reference/compound_stmts.html#the-with-statement) cuando se trabaja con archivos , por ejemplo, use 'with open (" x.txt ") como fh: '. Esto garantiza que si algo sale mal, se garantiza que el archivo estará cerrado. – Chris

+1

@Chris debe publicarlo como respuesta porque es la única solución válida y simple – JBernardo

+0

@JBernardo Gracias por la sugerencia - hecho. – Chris

Respuesta

8

Usted debe tratar de utilizar siempre la declaración cuando with trabajando con archivos Por ejemplo, usar algo como

with open("x.txt") as fh: 
    ...do something with the file handle fh 

Esto asegura que si algo va mal durante la ejecución del bloque with, y se produce una excepción, el archivo está garantizado que ser cerrado. Vea el with documentation para más información sobre esto.

Editar: después de un debate en los comentarios, parece que el OP necesita tener varios archivos abiertos al mismo tiempo y necesita utilizar datos de varios archivos a la vez. Claramente tener muchas declaraciones with anidadas, una por cada archivo abierto, no es una opción y va en contra del ideal de que "plano es mejor que anidado".

Una opción sería envolver el cálculo en un bloque try/finally. Por ejemplo

file_handles = [] 
try: 
    for file in file_list: 
     file_handles.append(open(file)) 

    # Do some calculations with open files 

finally: 
    for fh in file_handles: 
     fh.close() 

El finalmente bloque contiene código que se debe ejecutar después de cualquier bloque de try, except o else, incluso si una excepción ocurrió. Desde el documentation:

If finally is present, it specifies a "cleanup" handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is lost. The exception information is not available to the program during execution of the finally clause.

+0

Ok, pero el problema que tengo con este enfoque es que estoy abriendo algunos archivos en un bucle, p.'para fname en fname_list: file_list.append (open (fname))' porque más tarde tengo que hacer operaciones sobre la lista. Si utilizo el enfoque 'con ...', entonces todos los archivos se cierran en el ciclo, es decir, no puedo tener múltiples archivos abiertos. – tdc

+0

¿Necesita tener varios archivos abiertos simultáneamente? Si no es así, simplemente usa 'for fname in fname_list: con open (fname) como fh: '. Parte de su problema original era que dejaba los archivos abiertos y luego no tenía forma de cerrarlos, pero algo salió mal. Es más seguro abrir uno a la vez. – Chris

+0

Necesito tener varios archivos abiertos porque tengo varios conjuntos de datos en HDF5 y estoy usando pytables para acceder a ellos. Para usar las tablas piratas los archivos deben permanecer abiertos – tdc

7

algunas ideas:

  • uso siempre finally (o un bloque with) cuando se trabaja con archivos, por lo que están cerradas correctamente.
  • puede cerrar ciegamente los descriptores de archivos no estándar utilizando donde n es un número mayor que 2 (esto es específico de unix, por lo que es posible que desee consultar /proc/ipython_pid/fd/ para ver qué descriptores ha abierto hasta el momento).
  • puede inspeccionar la pila capturado marcos locales para ver si puede encontrar la referencia al archivo díscolo y cerrarla ... echar un vistazo a sys.last_traceback
Cuestiones relacionadas