147 votes

Comment sortir d'une clause if

Quelles sont les méthodes permettant de sortir prématurément d'une if clause ?

Il m'arrive parfois d'écrire du code et de vouloir mettre un break à l'intérieur d'une déclaration if pour se rappeler qu'elles ne peuvent être utilisées que pour les boucles.

Prenons l'exemple du code suivant :

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   ...
   if condition_b:
       # do something
       # and then exit the outer if block
   # more code here

Je pense à un moyen de le faire : en supposant que les cas de sortie se produisent à l'intérieur d'instructions if imbriquées, envelopper le code restant dans un gros bloc else. Exemple :

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   else:
       ...
       if condition_b:
           # do something
           # and then exit the outer if block
       else:
           # more code here

Le problème est qu'un plus grand nombre d'emplacements de sortie signifie plus de code imbriqué/indenté.

Je pourrais également écrire mon code de manière à ce que la fonction if les clauses doivent être aussi réduites que possible et ne pas nécessiter d'issues.

Quelqu'un connaît-il une bonne/meilleure façon de sortir d'une if clause ?

S'il existe des clauses "else-if" et "else" associées, je suppose que la sortie les ignore.

10voto

izzulmakin Points 430

Pour ce qui est de la question posée, mon approche consiste à mettre ces if à l'intérieur d'une boucle à une boucle

while (True):
    if (some_condition):
        ...
        if (condition_a):
            # do something
            # and then exit the outer if block
            break
        ...
        if (condition_b):
            # do something
            # and then exit the outer if block
            break
        # more code here
    # make sure it is looped once
    break

Testez-le :

conditions = [True,False]
some_condition = True

for condition_a in conditions:
    for condition_b in conditions:
        print("\n")
        print("with condition_a", condition_a)
        print("with condition_b", condition_b)
        while (True):
            if (some_condition):
                print("checkpoint 1")
                if (condition_a):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 2")
                    break
                print ("checkpoint 3")
                if (condition_b):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 4")
                    break
                print ("checkpoint 5")
                # more code here
            # make sure it is looped once
            break

5voto

Enki Points 116

D'une manière générale, ne le faites pas. Si vous imbriquez des "ifs" et que vous vous en séparez, c'est que vous vous y prenez mal.

Toutefois, si vous devez le faire :

if condition_a:
   def condition_a_fun():
       do_stuff()
       if we_wanna_escape:
           return
   condition_a_fun()
if condition_b:
   def condition_b_fun():
       do_more_stuff()
       if we_wanna_get_out_again:
           return
   condition_b_fun()

Note, les fonctions ne sont pas OBLIGATOIREMENT déclarées dans l'instruction if, elles peuvent être déclarées à l'avance ;) Ce serait un meilleur choix, car cela éviterait d'avoir à refactoriser un affreux if/then plus tard.

5voto

DonQuiKong Points 363

Il existe une autre méthode qui ne repose pas sur la définition de fonctions (parce que c'est parfois moins lisible pour de petits extraits de code), qui n'utilise pas de boucle while externe supplémentaire (qui pourrait nécessiter une appréciation spéciale dans les commentaires pour être compréhensible à première vue), qui n'utilise pas goto (...) et qui, surtout, vous permet de conserver votre niveau d'indentation pour le if externe, de sorte que vous n'ayez pas à commencer à imbriquer des choses.

if some_condition:
   ...
   if condition_a:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if: # if and only if exit_if wasn't set we want to execute the following code
   # keep doing something
   if condition_b:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if:
   # keep doing something

Cependant, si les extraits de code sont petits, il n'est pas nécessaire de suivre des boucles while qui ne se répéteront jamais et, après avoir compris à quoi servent les ifs intermédiaires, le tout est facilement lisible, en un seul endroit et avec la même indentation.

Et cela devrait être assez efficace.

4voto

Timbot Points 31

Voici une autre façon de procéder. Elle utilise une boucle for à un seul élément qui vous permet d'utiliser simplement continue. Cela évite d'avoir des fonctions supplémentaires sans raison. De plus, elle élimine les boucles while infinies potentielles.

if something:
    for _ in [0]:
        # Get x
        if not x:
            continue

        # Get y
        if not y:
            continue

        # Get z
        if not z:
            continue

        # Stuff that depends on x, y, and z

2voto

Smashery Points 13208

En fait, ce que vous décrivez, ce sont des déclarations de type "goto", qui sont généralement très critiquées. Votre deuxième exemple est beaucoup plus facile à comprendre.

Cependant, le nettoyant le serait encore :

if some_condition:
   ...
   if condition_a:
       your_function1()
   else:
       your_function2()

...

def your_function2():
   if condition_b:
       # do something
       # and then exit the outer if block
   else:
       # more code here

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