web-dev-qa-db-fra.com

Obtenir des détails sur les exceptions en Python

Je dois ouvrir et écrire dans environ 10 fichiers différents au sein d'une même boucle. Par exemple:

for i in range(0,10):
    try:
        a=5
        file1 = open("file1.txt",'w+')
        file2 = open("file2.txt",'w+')
        #... etc

        print(str(a),file=file1)
        print(str(a)+"hi",file=file2)
        # ... etc
    except: 
        #error handling

Maintenant, ce que j'aimerais faire, c'est pouvoir obtenir des informations sur les exceptions spécifiques, telles que le fichier en cours d'ouverture/écriture dans l'exception générale. De ma compréhension actuelle, je devrais faire quelque chose comme ceci pour réaliser ce que je veux:

for i in range(0,5):
    a=5
    try:
        file1 = open("file1.txt",'w+')
        print(str(a),file=file1)
    except: 
        #error handling for file1
    try:
        file2 = open("file2.txt",'w+')
        print(str(a)+"hi",file=file2)
    except: 
        #error handling for file2

... Ce qui va devenir extrêmement maladroit et peu attrayant lorsque je dois le faire pour environ 10 fichiers différents. Est-il possible d'extraire (par exemple) les informations de nom de fichier d'une exception générale, comme dans mon premier exemple? Essentiellement, l’exception peut signaler des erreurs telles que "erreur lors de l’écriture dans fichier1" sans essai/sauf spécialement pour les opérations fichier1.

edit: Il s’agit d’une simplification excessive des données en cours d’écriture dans le fichier. str (a) et str (a) + "hi" ne sont pas vraiment de bonnes représentations des données en cours d'écriture; fichier1 peut nécessiter un entier codé en dur, où fichier2 peut nécessiter une chaîne formatée avec plusieurs variables. généraliser le processus d'ouverture/écriture dans une boucle ne fonctionnera pas très bien.

14
user891876

Vous pouvez utiliser sys.exc_info pour obtenir des informations sur l'exception en cours de traitement, y compris l'objet exception lui-même. Une exception IOError contient toutes les informations dont vous avez besoin, y compris le nom du fichier, l'errno et une chaîne décrivant l'erreur:

import sys

try:
    f1 = open('example1')
    f2 = open('example2')
except IOError:
    type, value, traceback = sys.exc_info()
    print('Error opening %s: %s' % (value.filename, value.strerror))

L'exécution dans le bloc try sera évidemment toujours interrompue après la première exception.

25
Cairnarvon

Utilisez le module traceback :

traceback.print_exc()
11
rstackhouse

Vous mentionnez utiliser une boucle, mais vous n'utilisez pas réellement de boucle. Utilisez une boucle. De cette façon, vous pouvez écrire chaque fichier, un à la fois, dans un seul bloc try. Vous semblez ne rien faire avec les fichiers, sauf écrire une valeur pour chacun, vous n'avez donc pas besoin de les garder tous ouverts.

for filename in ['file1.txt', 'file2.txt', ...]:
    try:
        with open(filename, 'w+') as f:
            f.write(str(a)+"whatever")
    except IOError:
        print("Error occurred with", filename)

Éditer: si vous avez des choses très différentes à écrire dans les différents fichiers, créez un dictionnaire ou une autre structure de données stockant à l'avance le mappage entre les fichiers et les données, puis utilisez-le dans la boucle.

data = {'file1.txt': str(a), 'file2.txt': 'something else', 'file3.txt': str(a)+str(b)}

for filename, output in data.items():
    try:
        with open(filename, 'w+') as f:
            f.write(output)
    except IOError:
        print("Error occurred with", filename)
1
BrenBarn

Lorsque vous utilisez exc_type, value, exc_traceback = sys.exc_info(), notez que le nom de fichier qui a généré l’exception peut être obtenu de la manière suivante: 

exc_traceback.tb_frame.f_locals.get('filename')
1
ranaalisaeed