8 conseils de refactorisation pour rendre le code Python plus pythonique

1. Fusionner ajouter à la déclaration de liste

Nous commençons par un simple. Au lieu de déclarer une liste vide puis de l'ajouter, initialisez directement la liste avec tous les éléments. Cela raccourcit le code et rend l'intention plus explicite. Il fonctionne également légèrement mieux car il évite  append() l'appel de fonction à .

Il en va de même pour le remplissage d'autres types de collection tels que les ensembles et les dictionnaires.

2 Utilisez items() pour décompresser directement les valeurs du dictionnaire

Lors de l'itération sur un dictionnaire, vous avez besoin de la clé et de la valeur, puis n'accédez pas à la valeur manuellement. Au lieu de cela itérer dictionary.items(), ce qui vous donne à la fois des clés et des valeurs.

Cela enregistre les lignes que nous avions l'habitude d'attribuer  players et le code se lit maintenant plus naturellement et avec moins de répétitions.

teams_by_color = {"blue": ["Patrick", "Jessi"]}

for team_color in teams_by_color:
    players = teams_by_color[team_color]
    if is_winning(team_color):
        advance_level(players)

# -> refactor
for team_color, players in teams_by_color.items():
    if is_winning(team_color):
        advance_level(players)

3. Remplacez range(len) par enum

enumerate()Si nous devons parcourir la liste et garder une trace à la fois de l'index et de l'élément actuel, utilisez plutôt la fonction intégrée range(len). Cela renvoie l'index actuel et l'élément actuel sous forme de tuple. Nous pouvons donc regarder la valeur directement ici, et également accéder à l'élément avec un index.

for i in range(len(players)):
    print(i, players[i])

# -> refactor
for i, player in enumerate(players):
    print(i, player)

Enumerate Prend également un startparamètre facultatif. Si vous l'utilisez, le compteur commencera à partir de cette valeur. Notez cependant que les éléments commencent toujours par le premier.

for i, player in enumerate(players, start=1):
    print(i, player)

4. Remplacez le compteur de boucle manuel par un appel d'énumération

C'est très similaire à avant. Parfois, je vois du code qui effectue directement l'itération sur les éléments - ce qui n'est pas mauvais en soi - mais nécessite ensuite un compteur qui est incrémenté manuellement dans la boucle. Ici aussi, vous pouvez simplement utiliser  enumerate des fonctions. C'est plus simple et plus rapide.

i = 0
for player in players:
    print(i, player)
    i += 1

# -> refactor
for i, player in enumerate(players):
    print(i, player)

4.1 Ne pas mettre à jour manuellement les compteurs

Ne parcourez pas non plus la boucle et comptez tous les éléments manuellement si vous avez juste besoin de compter le nombre d'éléments. Au lieu de cela, utilisez simplement len()une fonction pour obtenir le nombre d'éléments dans la liste.

num_players = 0
for player in players:
    num_players += 1

# -> refactor
num_players = len(players)

5. Simplifiez la condition dans une instruction de retour

 Une pratique courante est celle-ci lorsque nous atteignons la fin d'une méthode et que nous voulons retourner  True un ou  . FalseSi la condition est  True, nous retournons  True. Sinon on revient en dernier  False. Cependant, retourner directement le résultat est plus concis :

def function():
    if isinstance(a, b) or issubclass(b, a):
        return True
    return False

# -> refactor
def function():
    return isinstance(a, b) or issubclass(b, a)

Une chose que nous devons noter ici est que cela ne peut être fait que si l'expression est évaluée à un booléen. isinstance()et issubclass()sont les deux fonctions qui renvoient un booléen, donc ça va. Mais dans l'exemple suivant, la première expression pythonistas est une liste au lieu d'un booléen.

S'il pythonistass'agit d'une liste non vide valide, cela renvoie la liste au lieu du booléen attendu, il s'agit probablement d'un bogue dans votre application. Donc, pour nous assurer que nous renvoyons un booléen ici, nous pouvons envelopper le retour dans un  bool()appel à la fonction.

def any_pythonistas():
    pythonistas = [coder for coder in coders if is_good_in_python(coder)]
    if pythonistas or self.is_pythonista():
        return True
    return False

# -> refactor
def any_hats():
    pythonistas = [coder for coder in coders if is_good_in_python(coder)]
    return bool(pythonistas or self.is_pythonista())

6. Fusionner les blocs répétés dans les conditions

Nous devons toujours rechercher des opportunités pour supprimer le code en double. Un bon endroit pour le faire est s'il if …elify a plusieurs blocs identiques dans la chaîne.

Dans cet exemple, if et  elif les deux aboutissent à la même fonction d'exécution. Nous pouvons donc utiliser orla combinaison des deux premiers blocs pour supprimer les appels répétés à la fonction. Maintenant, si nous devons changer process_standard_payment()une ligne, nous pouvons le faire à un seul endroit au lieu de deux.

def process_payment(payment, currency):
    if currency == "USD":
        process_standard_payment(payment)
    elif currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

# -> refactor
def process_payment(payment, currency):
    if currency == "USD" or currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

7. Remplacer plusieurs comparaisons de la même variable par l'opérateur in

Nous pouvons encore refactoriser le code précédent. Puisque nous vérifions la même variable à plusieurs reprises par rapport à plusieurs valeurs, nous pouvons utiliser l'opérateur in pour la raccourcir. Si la valeur de la devise est dans la liste définie, nous effectuons une opération dédiée.

def process_payment(payment, currency):
    if currency == "USD" or currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

# -> refactor
def process_payment(payment, currency):
    if currency in ["USD", "EUR"]:
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

Pour améliorer encore cela, nous devrions utiliser une collection here . Il est plus rapide de rechercher des valeurs dans un ensemble, et nous voulons de toute façon des éléments uniques ici, donc les ensembles sont le meilleur choix.

# -> refactor
def process_payment(payment, currency):
    if currency in {"USD", "EUR"}:
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

8. Remplacez yield dans la boucle for par yield from

Il s'agit d'une technique avancée si vous êtes déjà familiarisé avec les générateurs. Une astuce souvent négligée est que  yield les mots-clés Python ont une contrepartie itérable yield from.

Si vous avez un objet itérable comme une liste, au lieu de dire for item in iterable: yield item, vous pouvez simplement dire yield from iterable. Ceci est plus court et élimine les boucles manuelles sur l'itérable, ce qui peut également améliorer les performances.

def get_content(entry):
    for block in entry.get_blocks():
        yield block

# -> refactor
def get_content(entry):
    yield from entry.get_blocks()

players = []
players.append("Patrick")
players.append("Max")
players.append("Jessi")

# -> refactor
players = ["Patrick", "Max", "Jessi"]

Guess you like

Origin blog.csdn.net/veratata/article/details/128793226