Detectar una excepción al usar una declaración 'with' de Python

Resuelto grigoryvp asked hace 15 años • 6 respuestas

No puedo entender cómo manejar la excepción para la declaración 'con' de Python. Si tengo un código:

with open("a.txt") as f:
    print f.readlines()

Realmente quiero manejar la 'excepción de archivo no encontrado' para poder hacer algo. pero no puedo escribir

with open("a.txt") as f:
    print f.readlines()
except:
    print 'oops'

y no puedo escribir

with open("a.txt") as f:
    print f.readlines()
else:
    print 'oops'

Incluir withuna declaración try/except tampoco funciona y no se genera una excepción. ¿Qué puedo hacer para procesar la falla dentro de withla declaración de forma pitónica?

grigoryvp avatar Apr 03 '09 20:04 grigoryvp
Aceptado

Esta solución mantendrá el código with-block fuera de la cláusula try-except.

try:
    f = open('foo.txt')
except FileNotFoundError:
    print('error')
else:
    with f:
        print f.readlines()
Douglas Leeder avatar Apr 03 '2009 13:04 Douglas Leeder

La mejor forma "Pythonic" de hacer esto, explotando la withdeclaración, aparece como Ejemplo #6 en PEP 343 , que brinda los antecedentes de la declaración.

from contextlib import contextmanager

@contextmanager
def opened_w_error(filename, mode="r"):
    try:
        f = open(filename, mode)
    except IOError, err:
        yield None, err
    else:
        try:
            yield f, None
        finally:
            f.close()

Se utiliza de la siguiente manera:

with opened_w_error("/etc/passwd", "a") as (f, err):
    if err:
        print "IOError:", err
    else:
        f.write("guido::0:0::/:/bin/sh\n")
 avatar May 22 '2011 20:05

Detectar una excepción al usar una declaración 'with' de Python

La declaración with ha estado disponible sin __future__importación desde Python 2.6 . Puedes obtenerlo desde Python 2.5 (¡pero en este punto es momento de actualizarlo!) con:

from __future__ import with_statement

Esto es lo más parecido a corregir que tienes. Ya casi has llegado, pero withno tiene una exceptcláusula:

with open("a.txt") as f: 
    print(f.readlines())
except:                    # <- with doesn't have an except clause.
    print('oops')

El método de un administrador de contexto __exit__, si regresa, Falsevolverá a generar el error cuando finalice. Si regresa True, lo suprimirá. El openincorporado __exit__no regresa True, por lo que solo necesita anidarlo en un intento, excepto en el bloque:

try:
    with open("a.txt") as f:
        print(f.readlines())
except Exception as error: 
    print('oops')

Y el texto estándar: no utilice un código simple except:que detecte BaseExceptiony cualquier otra posible excepción y advertencia. Sea al menos tan específico como Exception, y para este error, tal vez detecte IOError. Detecte únicamente los errores que esté preparado para manejar.

Entonces, en este caso, harías:

>>> try:
...     with open("a.txt") as f:
...         print(f.readlines())
... except IOError as error: 
...     print('oops')
... 
oops
Russia Must Remove Putin avatar Jul 25 '2015 05:07 Russia Must Remove Putin