with tutorial para framework español djangoproject con applications python exception with-statement

python - para - tutorial django



¿Cómo "con" es mejor que try/catch para abrir un archivo en Python? (3)

Obtuve que la declaración with ayuda te ayuda a convertir esto:

try: f = open(my_file) do_stuff_that_fails() except: pass finally: f.close()

Dentro:

with open(my_file) as f: do_stuff_that_fails()

¿Pero cómo es eso mejor? Todavía tienes que manejar el caso con el archivo que no se puede abrir (como pedirle al usuario que le diga que no tiene permisos), así que en realidad tendrías:

try: with open(my_file) as f: do_stuff_that_fails() except (IOError, OSError, Failure) as e: do_stuff_when_it_doesnt_work()

Lo cual es equivalente a:

try: f = open(my_file) do_stuff_that_fails() except (IOError, OSError, Faillure) as e: do_stuff_when_it_doesnt_work() finally: f.close()

Sí, ganó dos líneas, pero agregó un nivel de anidación que no facilita la lectura. ¿El propósito de la declaración with para guardar dos líneas o me falta algo?

Parece mucho agregar una palabra clave solo para eso, así que siento que hay alguna sintaxis para manejar la prueba adicional, excepto que no sé.


En el ejemplo que das, no es mejor. Lo mejor es detectar las excepciones tan cerca del punto donde se lanzan para evitar la captura de excepciones no relacionadas del mismo tipo.

try: file = open(...) except OpenErrors...: # handle open exceptions else: try: # do stuff with file finally: file.close()

Como lamentablemente es muy detallado, la declaración with no permite capturar excepciones lanzadas durante su evaluación. Hubo una suggestion para agregar manejo de excepciones a este efecto en la lista de correo:

with open(...) as file: # do stuff with file except OpenErrors...: # handle open exceptions

Pero esto fue derribado .

Finalmente, vale la pena señalar que puede ingresar y salir directamente de los administradores de contexto de la siguiente manera:

file = open(...).__enter__() file.__exit__(typ, val, tb)

Esto se describe con más detalle aquí y here .

Como una guía general, with declaraciones sobresalientes para los casos donde no se esperan excepciones, y el comportamiento predeterminado "entrar / abrir / adquirir" es adecuado. Los ejemplos incluyen archivos necesarios y bloqueo simple.


Es para la gestión de recursos ... no por la forma en que reaccionas a una excepción de lo contrario :)

No hay forma de "olvidar" f.close() cuando se usa with . De esta manera, cumple la misma función que using en C #.

Feliz codificación.


Para empezar, ayuda a prevenir el problema que ha introducido en su try ... finally ... ejemplo.

La forma en que lo ha estructurado, si se lanza una excepción al intentar abrir el archivo, nunca vinculará un archivo abierto con el nombre f , lo que NameError lugar a un NameError en la cláusula finally (si f nunca se ha vinculado dentro del alcance) ) o algo completamente inesperado (si lo tiene).

La estructura correcta (equivalente a with ) es:

f = open(my_file) try: do_stuff_that_fails() finally: f.close()

(nota: no hay necesidad de una cláusula except si no tienes nada que hacer allí).

Su segundo ejemplo igualmente está mal, y debería estructurarse como:

try: f = open(my_file) try: do_stuff_that_fails() except EXPECTED_EXCEPTION_TYPES as e: do_stuff_when_it_doesnt_work() finally: f.close() except (IOError, OSError) as e: do_other_stuff_when_it_we_have_file_IO_problems()

El segundo es (como se indica en otra respuesta) que no puede olvidarse de llamar a f.close() .

Por cierto, el término es "gestión de contexto", no "gestión de recursos": la declaración with maneja contextos , algunos de los cuales pueden ser recursos, pero otros no. Por ejemplo, también se usa con decimal para establecer un contexto decimal para un bloque de código en particular.

Finalmente (respondiendo a su comentario a la respuesta anterior) nunca debe confiar en la semántica de refcount para manejar recursos en Python. Jython, IronPython y PyPy tienen una semántica sin refcount, y no hay nada que impida que CPython vaya por el otro lado (aunque es muy poco probable para el futuro inmediato). En un ciclo cerrado (por ejemplo, os.walk ) es muy fácil agotar los identificadores de archivo si el código que se basa en la semántica de refcount se ejecuta en una máquina virtual con un comportamiento diferente.