2009-09-16 11 views
26

Digamos que queremos implementar un equivalente de PHP file_get_content.cómo obtener el contenido de un pequeño archivo ascii en python?

¿Cuál es la mejor práctica? (elegante y confiable)

Aquí hay alguna proposición, ¿están correctas?

usando with declaración:

def file_get_contents(filename): 
    with file(filename) as f: 
     s = f.read() 
    return s 

es el uso estándar open() seguro?

def file_get_contents(filename): 
    return open(filename).read() 

¿Qué sucede con el descriptor de archivo en cualquiera de las soluciones?

Respuesta

39

En la implementación actual del CPython, ambos En general, cierre inmediatamente el archivo. Sin embargo, el lenguaje Python no ofrece ninguna garantía para el segundo: el archivo eventualmente se cerrará, pero el finalizador no se podrá llamar hasta el próximo ciclo de gc. Implementaciones como Jython e IronPython funcionarán así, por lo que es una buena práctica cerrar de forma explícita tus archivos.

Yo diría que usar la primera solución es la mejor práctica, aunque generalmente se prefiere open a file. Observe que puede acortarlo un poco, aunque si lo prefiere la brevedad del segundo ejemplo:

def file_get_contents(filename): 
    with open(filename) as f: 
     return f.read() 

La parte __exit__ del gestor de contexto ejecutará cuando salga del cuerpo de cualquier razón, incluidas las excepciones y volviendo de la función - no es necesario usar una variable intermedia.

+1

de PEP 343: http://www.python.org/dev/peps/pep-0343 Tenga en cuenta que no estamos garantizando que la cláusula finally se ejecuta inmediatamente después de que el objeto se convierte en generador sin uso, a pesar de que esto es cómo funcionará en CPython. Esto es similar a los archivos de auto-cierre: mientras que una implementación de referencia, contando como CPython desasigna un objeto tan pronto como la última referencia a ella desaparece, las implementaciones que utilizan otros algoritmos de GC no hacen la misma garantía. Esto se aplica a Jython, IronPython y, probablemente, a Python que se ejecuta en Parrot. – kriss

+0

@kriss: Tenga en cuenta que eso no contradice la afirmación acerca de cómo ejecutar '__exit__' cuando sale del cuerpo - que sólo detalla qué sucede si no lo hace ** ** salir del cuerpo por tener un generador suspendido dentro del gestor de contexto, y cómo Python lo obligará a irse al plantear una excepción. – Brian

2

with se asegurará de que el archivo se cierre cuando se deja el bloque.

En su segundo ejemplo, el identificador del archivo puede permanecer abierto (Python no garantiza que esté cerrado o si no lo hace explícitamente).

+4

No del todo. En CPython, el archivo se cierra tan pronto como el descriptor de archivo se sale del alcance, por cierto cuando la función vuelve. (Comprobé el origen de Python, ya que este punto apareció en otro lugar recientemente). En IronPython y Jython, el archivo se cerrará cuando el objeto del archivo sea basura, pero no hay garantías de cuándo será eso. –

+0

Si no usa 'con', ¿el archivo está cerrado incluso en el caso de una excepción? –

+1

@Hank Gay: si no "con" no hay garantías, el descriptor de archivo del sistema operativo puede quedar abierto. –

1
import os 

def file_get_contents(filename): 
    if os.path.exists(filename): 
    fp = open(filename, "r") 
    content = fp.read() 
    fp.close() 
    return content 

Este caso devolverá None si el archivo no existe y el descriptor de archivo se cerrará antes de que salgamos de la función.

+4

esto pasa por el punto de utilizar 'with' - este código tiene la misma debilidad que explícita nueva/delete' en código C++' - en el caso de cualquier excepción que interviene ante el código de limpieza, la limpieza simplemente no sucede. En las versiones anteriores de Python, uno podía envolver este ejemplo en 'try/catch/finally', pero los niños más geniales están usando' with'. – PaulMcG

+0

Esto no tiene sentido en la cuestión de la fiabilidad. Agrega funciones no deseadas (verifique la existencia del archivo), y no es particularmente elegante (importando el código y la longitud del código). – vaab

3

El uso de la declaración with es en realidad la mejor manera de ser seguro que el archivo está realmente cerrado.

Dependiendo del comportamiento recolector de basura para esta tarea podría funcionar, pero en este caso, no es una buena manera de estar seguro en todos los casos, por lo ...

-1

También puede utilizar la función de Python v3:

>>> ''.join(open('htdocs/config.php', 'r').readlines()) 
"This is the first line of the file.\nSecond line of the file" 

Leer más aquí http://docs.python.org/py3k/tutorial/inputoutput.html

+1

Tenga cuidado al publicar copiar y pegar las respuestas al pie de página o verbatim a múltiples preguntas, estas tienden a ser señaladas como "spam" por la comunidad. Si está haciendo esto, generalmente significa que las preguntas son duplicadas, por lo tanto, márquelas como tales. http://stackoverflow.com/questions/1433577 – Kev

Cuestiones relacionadas