Attraper une exception lors de l'utilisation D'une instruction Python 'with'

À ma honte, Je ne peux pas comprendre comment gérer l'exception pour l'instruction python 'with'. Si j'ai un code:

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

Je veux vraiment gérer 'file not found exception' afin de faire quelque chose. Mais je ne peux pas écrire

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

Et ne peut pas écrire

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

Enfermer 'with' dans une instruction try / except ne fonctionne pas autrement: exception n'est pas levée. Que puis-je faire pour traiter l'échec à l'intérieur de l'instruction 'with' d'une manière pythonique?

209
demandé sur cdleary 2009-04-03 17:00:25

4 réponses

from __future__ import with_statement

try:
    with open( "a.txt" ) as f :
        print f.readlines()
except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available
    print 'oops'

Si vous voulez une gestion différente des erreurs de l'appel ouvert par rapport au code de travail, vous pouvez faire:

try:
    f = open('foo.txt')
except IOError:
    print('error')
else:
    with f:
        print f.readlines()
192
répondu Douglas Leeder 2011-03-08 16:36:12

La meilleure façon "pythonique" de le faire, en exploitant l'instruction with, est répertoriée comme exemple #6 dans PEP 343, qui donne l'arrière-plan de l'instruction.

@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()

Utilisé comme suit:

with opened_w_error("/etc/passwd", "a") as (f, err):
    if err:
        print "IOError:", err
    else:
        f.write("guido::0:0::/:/bin/sh\n")
58
répondu Josh Caswell 2013-01-06 20:16:13

Capture d'une exception lors de l'utilisation D'une instruction Python 'with'

L'instruction with Est disponible sans __future__ import depuis Python 2.6 . Vous pouvez l'obtenir comme dès python 2.5 (mais à ce stade, il est temps de mettre à niveau!) avec:

from __future__ import with_statement

Voici la chose la plus proche à corriger que vous avez. Vous y êtes presque, mais with n'a pas de clause except:

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

La méthode __exit__ D'un gestionnaire de contexte, si elle returns False relancera l'erreur quand elle se termine. S'il retourne True, il le supprimera. Le open intégré {[7] }ne retourne pas True, donc vous avez juste besoin de l'imbriquer dans un essai, sauf block:

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

Et standard boilerplate: n'utilisez pas un except: nu qui attrape BaseException et toutes les autres exceptions et avertissements possibles. Être au moins aussi spécifique que Exception, et pour cette erreur, peut-être attraper IOError. Ne détectez que les erreurs que vous êtes prêt à gérer.

Donc dans ce cas, vous faire:

>>> try:
...     with open("a.txt") as f:
...         print(f.readlines())
... except IOError as error: 
...     print('oops')
... 
oops
44
répondu Aaron Hall 2018-02-20 00:31:53

Une autre alternative pourrait être de vérifier si le fichier existe en premier, puis de procéder à l'instruction with. Exemple:

import os

if not os.path.exists(file_path): # check first if file exsits
   print("file not found")

else:
    with open("a.txt") as f: # proceed as usual
        print f.readlines()
0
répondu yosemite_k 2018-04-23 13:28:15