Detectar una excepción al usar una declaración 'with' de Python
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 with
una declaración try/except tampoco funciona y no se genera una excepción. ¿Qué puedo hacer para procesar la falla dentro de with
la declaración de forma pitónica?
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()
La mejor forma "Pythonic" de hacer esto, explotando la with
declaració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")
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 with
no tiene una except
clá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, False
volverá a generar el error cuando finalice. Si regresa True
, lo suprimirá. El open
incorporado __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 BaseException
y 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