224 votes

Manière pythonique d'éviter les instructions "if x: return x"

J'ai une méthode qui appelle 4 autres méthodes dans l'ordre pour vérifier les conditions spécifiques, et retourne immédiatement (pas de vérification ci-dessous) à chaque fois que l'on revient à quelque chose de Truthy.

def check_all_conditions():
    x = check_size()
    if x:
        return x

    x = check_color()
    if x:
        return x

    x = check_tone()
    if x:
        return x

    x = check_flavor()
    if x:
        return x
    return None

Il semble que beaucoup de bagages code. Au lieu de tous les 2 en cas de déclaration, je préfère faire quelque chose comme:

x and return x

Mais qui n'est pas valide Python. Ai-je raté une solution simple et élégante ici? D'ailleurs, dans cette situation, ces quatre vérifier les méthodes peuvent être coûteux, donc je n'ai pas envie de les appeler plusieurs fois.

395voto

timgeb Points 5966

Alternativement vous pouvez enchaîner à réponse fine de Martijn, . Cela retourne la première valeur de truthy, ou s’il n’y a pas de valeur truthy :

Démo :

281voto

Martijn Pieters Points 271458

Vous pouvez utiliser une boucle:

conditions = (check_size, check_color, check_tone, check_flavor)
for condition in conditions:
    result = condition()
    if result:
        return result

Ceci a l'avantage que vous pouvez maintenant faire le nombre de conditions variables.

Vous pouvez utiliser map() + filter() (le Python 3 versions, utilisez l' future_builtins versions de Python 2) pour obtenir la première valeur correspondante:

try:
    # Python 2
    from future_builtins import map, filter
except ImportError:
    # Python 3
    pass

conditions = (check_size, check_color, check_tone, check_flavor)
return next(filter(None, map(lambda f: f(), conditions)), None)

mais si c'est plus lisible est discutable.

Une autre option est d'utiliser un générateur d'expression:

conditions = (check_size, check_color, check_tone, check_flavor)
checks = (condition() for condition in conditions)
return next((check for check in checks if check), None)

91voto

Jack Aidley Points 3993

Ne pas changer

Il y a des autres moyens de le faire comme le montrent les divers autres réponses. Aucun n’est aussi clair que votre code d’origine.

85voto

Wayne Werner Points 10172

Dans efficacement la même réponse que timgeb, mais vous pouvez utiliser parenthèse pour le formatage des plus agréable :

75voto

Phil Frost Points 1110

Selon Bouclés du droit, vous pouvez vous rendre ce code plus lisible par le fractionnement de deux préoccupations:

  • Quelles sont les choses que dois-je vérifier?
  • A une chose a renvoyé true?

en deux fonctions:

def all_conditions():
    yield check_size()
    yield check_color()
    yield check_tone()
    yield check_flavor()

def check_all_conditions():
    for condition in all_conditions():
        if condition:
            return condition
    return None

Ceci évite:

  • compliqué structures logiques
  • vraiment le long des lignes de
  • la répétition

...tout en préservant un linéaire, facile à lire des flux.

Vous pouvez probablement aussi venir avec encore plus de noms de fonction, en fonction de votre cas particulier, qui le rendent encore plus lisible.

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