129 votes

Attraper une exception et continuer le bloc d'essai en Python

Puis-je retourner à l'exécution du bloc try après qu'une exception se soit produite?

Par exemple:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

contre.

try:
    do_smth1()
    do_smth2()
except:
    ??? # mot magique pour passer à do_smth2() s'il y avait une exception dans do_smth1

8voto

IfLoop Points 59461

Une façon de gérer cela est avec un générateur. Au lieu d'appeler la fonction, yield it ; puis tout ce qui consomme le générateur peut renvoyer le résultat de son appel dans le générateur, ou un signal si le générateur échoue : Le trampoline qui accomplit ce qui précède pourrait ressembler à ceci:

def consume_exceptions(gen):
    action = next(gen)
    while True:
        try:
            result = action()
        except Exception:
            # si l'action échoue, envoie un signal
            result = None

        try:
            action = gen.send(result)
        except StopIteration:
            # si le générateur est entièrement utilisé, le résultat est la valeur de retour.
            return result

Un générateur qui serait compatible avec cela ressemblerait à ceci:

def do_smth1():
    1 / 0

def do_smth2():
    print "YAY"

def do_many_things():
    a = yield do_smth1
    b = yield do_smth2
    yield "Done"

>>> consume_exceptions(do_many_things())
YAY

Notez que do_many_things() n'appelle pas do_smth*, il les renvoie simplement, et consume_exceptions les appelle en son nom

4voto

sweeneyrod Points 3354

Je ne pense pas que tu veuilles faire ça. La bonne manière d'utiliser une instruction try en général est aussi précisément que possible. Je pense qu'il serait préférable de faire :

try:
    do_smth1()
except Stmnh1Exception:
    # gérer Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # gérer Stmnh2Exception

3voto

Dan Points 3053

En fonction de l'endroit et de la fréquence à laquelle vous devez le faire, vous pourriez également écrire une fonction qui le fait pour vous :

def live_dangerously(fn, *args, **kw):
    try:
        return fn(*args, **kw)
    except Exception:
        pass

live_dangerously(do_smth1)
live_dangerously(do_smth2)

Mais comme d'autres réponses l'ont noté, avoir un except nul est généralement un signe qu'il y a quelque chose d'autre qui ne va pas avec votre code.

2voto

wisedesign Points 21

Cela peut être fait avec exec() dans une fonction personnalisée, une liste de chaînes de caractères, et une boucle for.

La fonction avec exec():

def try_it(string):
    try:
        exec(string)
        print(f'Fait : {string}')
    except:
        print(f'Erreur. Impossible de faire : {string}')

Plus sur exec():
exec(objet)
Cette fonction prend en charge l'exécution dynamique du code Python. objet doit être soit une chaîne de caractères, soit un objet de code.

Exemple de liste de chaînes et boucle for:

do_smth_list = ['do_smth1()', 'do_smth2()', 'do_smth3()'] 

for smth in do_smth_list:
    try_it(smth)

1voto

DeWil Points 102

special_func pour éviter la répétition try-except :

def special_func(test_case_dict):
    final_dict = {}
    exception_dict = {}

    def try_except_avoider(test_case_dict):

        try:
            for k,v in test_case_dict.items():
                final_dict[k]=eval(v) #Si aucune exception, évalue la fonction et l'ajoute à final_dict

        except Exception as e:
            exception_dict[k]=e #extrait l'exception
            test_case_dict.pop(k)
            try_except_avoider(test_case_dict) #fonction récursive pour gérer les fonctions restantes

        finally:  #nettoyage
            final_dict.update(exception_dict)
            return final_dict #combine le dictionnaire des exceptions et final_dict

    return try_except_avoider(test_case_dict) 

Exécuter le code :

def add(a,b):
    return (a+b)
def sub(a,b):
    return (a-b)
def mul(a,b):
    return (a*b)

case = {"AddFunc":"add(8,8)","SubFunc":"sub(p,5)","MulFunc":"mul(9,6)"}
solution = special_func(case)

La sortie ressemble à :

{'AddFunc': 16, 'MulFunc': 54, 'SubFunc': NameError("name 'p' is not defined")}

Pour convertir en variables :

locals().update(solution)

Les variables ressembleraient à :

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X