Comment écrire un beau code Python avec PEP 8

Comment écrire un beau code Python avec PEP 8

PEP 8, parfois orthographié PEP8 ou PEP-8, est un document qui fournit des directives et des meilleures pratiques sur la façon d'écrire du code Python. Il a été écrit en 2001 par Guido van Rossum, Barry Varsovie et Nick Coghlan. L'objectif principal de PEP 8 est d'améliorer la lisibilité et la cohérence du code Python.

PEP signifie Python Enhancement Proposal, et il y en a plusieurs. Un PEP est un document qui décrit les nouvelles fonctionnalités proposées pour Python et documente les aspects de Python, comme la conception et le style, pour la communauté.

Ce didacticiel décrit les principales directives énoncées dans PEP 8. Il est destiné aux programmeurs débutants à intermédiaires, et en tant que tel, je n'ai pas couvert certains des sujets les plus avancés. Vous pouvez en apprendre davantage sur ces derniers en lisant la documentation complète dePEP 8.

By the end of this tutorial, you’ll be able to:

  • Écrire du code Python conforme à PEP 8

  • Comprendre le raisonnement derrière les lignes directrices énoncées dans PEP 8

  • Configurez votre environnement de développement pour pouvoir commencer à écrire du code Python conforme à PEP 8

Free Bonus:5 Thoughts On Python Mastery, un cours gratuit pour les développeurs Python qui vous montre la feuille de route et l'état d'esprit dont vous aurez besoin pour faire passer vos compétences Python au niveau supérieur.

Pourquoi nous avons besoin de PEP 8

"La lisibilité compte."

-The Zen of Python

PEP 8 existe pour améliorer la lisibilité du code Python. Mais pourquoi la lisibilité est-elle si importante? Pourquoi l'écriture de code lisible est-elle l'un des principes directeurs du langage Python?

Comme l'a dit Guido van Rossum, «le code est lu beaucoup plus souvent qu'il n'est écrit». Vous pouvez passer quelques minutes ou une journée entière à écrire un morceau de code pour traiter l'authentification des utilisateurs. Une fois que vous l’avez écrit, vous ne l’écrirez plus jamais. Mais vous devrez certainement le relire. Ce morceau de code peut faire partie d'un projet sur lequel vous travaillez. Chaque fois que vous revenez à ce fichier, vous devez vous rappeler ce que fait ce code et pourquoi vous l'avez écrit, donc la lisibilité est importante.

Si vous débutez avec Python, il peut être difficile de se souvenir de ce que fait un morceau de code quelques jours ou semaines après l'avoir écrit. Si vous suivez PEP 8, vous pouvez être sûr que vous avez bien nommé vos variables. Vous saurez que vous avez ajouté suffisamment d’espace afin de pouvoir suivre plus facilement les étapes logiques de votre code. Vous aurez également bien commenté votre code. Tout cela signifie que votre code est plus lisible et plus facile à consulter. En tant que débutant, suivre les règles de PEP 8 peut rendre l'apprentissage de Python une tâche beaucoup plus agréable.

Suivre PEP 8 est particulièrement important si vous recherchez un travail de développement. L'écriture d'un code clair et lisible montre du professionnalisme. Cela indiquera à un employeur que vous comprenez comment bien structurer votre code.

Si vous avez plus d'expérience dans l'écriture de code Python, vous devrez peut-être collaborer avec d'autres. L'écriture de code lisible ici est cruciale. D'autres personnes, qui ne vous ont peut-être jamais rencontré ou vu votre style de codage auparavant, devront lire et comprendre votre code. Le fait d'avoir des directives que vous suivez et reconnaissez facilitera la lecture de votre code par d'autres personnes.

Conventions de nommage

"Explicite vaut mieux qu'implicite."

-The Zen of Python

Lorsque vous écrivez du code Python, vous devez nommer beaucoup de choses: variables, fonctions, classes, packages, etc. Choisir des noms sensés vous fera économiser du temps et de l'énergie plus tard. Vous serez en mesure de comprendre, à partir du nom, ce qu'une certaine variable, fonction ou classe représente. Vous éviterez également d'utiliser des noms inappropriés qui pourraient entraîner des erreurs difficiles à déboguer.

Note: N'utilisez jamais les noms de lettre uniquel,O ouI car ils peuvent être confondus avec1 et0, selon la police de caractères :

O = 2  # This may look like you're trying to reassign 2 to zero

Styles de dénomination

Le tableau ci-dessous décrit certains des styles de dénomination courants dans le code Python et quand vous devez les utiliser:

Type Convention de dénomination Exemples

Une fonction

Utilisez un ou plusieurs mots en minuscules. Séparez les mots par des traits de soulignement pour améliorer la lisibilité.

function,my_function

Variable

Utilisez une seule lettre, un mot ou des mots minuscules. Séparez les mots avec des traits de soulignement pour améliorer la lisibilité.

x,var,my_variable

Classe

Commencez chaque mot par une majuscule. Ne séparez pas les mots par des traits de soulignement. Ce style est appelé étui camel.

Model,MyClass

Méthode

Utilisez un ou plusieurs mots en minuscules. Séparez les mots avec des traits de soulignement pour améliorer la lisibilité.

class_method,method

Constant

Utilisez une seule lettre, un mot ou des mots en majuscules. Séparez les mots avec des traits de soulignement pour améliorer la lisibilité.

CONSTANT,MY_CONSTANT,MY_LONG_CONSTANT

Module

Utilisez un ou plusieurs mots courts et minuscules. Séparez les mots avec des traits de soulignement pour améliorer la lisibilité.

module.py,my_module.py

Paquet

Utilisez un ou plusieurs mots courts et minuscules. Ne séparez pas les mots par des traits de soulignement.

package,mypackage

Voici quelques-unes des conventions de dénomination courantes et des exemples d'utilisation. Mais pour écrire du code lisible, vous devez toujours faire attention à votre choix de lettres et de mots. En plus de choisir les styles de dénomination corrects dans votre code, vous devez également choisir les noms avec soin. Vous trouverez ci-dessous quelques conseils sur la façon de le faire le plus efficacement possible.

Comment choisir des noms

Le choix des noms pour vos variables, fonctions, classes, etc. peut être difficile. Vous devriez réfléchir à vos choix de dénomination lors de l'écriture de code car cela rendra votre code plus lisible. La meilleure façon de nommer vos objets en Python est d'utiliser des noms descriptifs pour clarifier ce que l'objet représente.

Lorsque vous nommez des variables, vous pouvez être tenté de choisir des noms simples en minuscules à une seule lettre, commex. Mais, à moins que vous n'utilisiezx comme argument d'une fonction mathématique, ce que représentex n'est pas clair. Imaginez que vous stockez le nom d'une personne sous forme de chaîne et que vous souhaitez utiliser le découpage de chaîne pour formater son nom différemment. Vous pourriez vous retrouver avec quelque chose comme ça:

>>>

>>> # Not recommended
>>> x = 'John Smith'
>>> y, z = x.split()
>>> print(z, y, sep=', ')
'Smith, John'

Cela fonctionnera, mais vous devrez garder une trace de ce que représententx,y etz. Cela peut également prêter à confusion pour les collaborateurs. Un choix de noms beaucoup plus clair serait quelque chose comme ceci:

>>>

>>> # Recommended
>>> name = 'John Smith'
>>> first_name, last_name = name.split()
>>> print(last_name, first_name, sep=', ')
'Smith, John'

De même, pour réduire la quantité de frappe que vous faites, il peut être tentant d'utiliser des abréviations lors du choix des noms. Dans l'exemple ci-dessous, j'ai défini une fonctiondb() qui prend un seul argumentx et le double:

# Not recommended
def db(x):
    return x * 2

À première vue, cela pourrait sembler un choix judicieux. db() pourrait facilement être une abréviation pour double. Mais imaginez revenir à ce code dans quelques jours. Vous avez peut-être oublié ce que vous tentiez d'accomplir avec cette fonction, et cela rendrait difficile de deviner comment vous l'avez abrégée.

L'exemple suivant est beaucoup plus clair. Si vous revenez à ce code quelques jours après l'avoir écrit, vous pourrez toujours lire et comprendre l'objectif de cette fonction:

# Recommended
def multiply_by_two(x):
    return x * 2

La même philosophie s'applique à tous les autres types de données et objets en Python. Essayez toujours d'utiliser les noms les plus concis mais descriptifs possibles.

Disposition du code

"Beau vaut mieux que laid."

-The Zen of Python

La façon dont vous disposez votre code a un rôle énorme dans sa lisibilité. Dans cette section, vous apprendrez comment ajouter des espaces verticaux pour améliorer la lisibilité de votre code. Vous apprendrez également à gérer la limite de 79 caractères recommandée dans PEP 8.

Lignes vides

Les espaces blancs verticaux ou les lignes vides peuvent améliorer considérablement la lisibilité de votre code. Le code regroupé peut être écrasant et difficile à lire. De même, trop de lignes vides dans votre code le rendent très clairsemé, et le lecteur devra peut-être faire défiler plus que nécessaire. Vous trouverez ci-dessous trois directives clés sur l'utilisation des espaces blancs verticaux.

Surround top-level functions and classes with two blank lines. Les fonctions et classes de niveau supérieur doivent être assez autonomes et gérer des fonctionnalités distinctes. Il est logique de placer un espace vertical supplémentaire autour d'eux, afin qu'il soit clair qu'ils sont séparés:

class MyFirstClass:
    pass


class MySecondClass:
    pass


def top_level_function():
    return None

Surround method definitions inside classes with a single blank line. À l'intérieur d'une classe, les fonctions sont toutes liées les unes aux autres. Il est recommandé de ne laisser qu'une seule ligne entre eux:

class MyClass:
    def first_method(self):
        return None

    def second_method(self):
        return None

Use blank lines sparingly inside functions to show clear steps. Parfois, une fonction compliquée doit effectuer plusieurs étapes avant l'instructionreturn. Pour aider le lecteur à comprendre la logique de la fonction, il peut être utile de laisser une ligne vierge entre chaque étape.

Dans l'exemple ci-dessous, il existe une fonction pour calculer la variance d'une liste. Il s'agit d'un problème en deux étapes, j'ai donc indiqué chaque étape en laissant une ligne vide entre elles. Il y a également une ligne vide avant l'instructionreturn. Cela aide le lecteur à voir clairement ce qui est retourné:

def calculate_variance(number_list):
    sum_list = 0
    for number in number_list:
        sum_list = sum_list + number
    mean = sum_list / len(number_list)

    sum_squares = 0
    for number in number_list:
        sum_squares = sum_squares + number**2
    mean_squares = sum_squares / len(number_list)

    return mean_squares - mean**2

Si vous utilisez soigneusement les espaces verticaux, cela peut grandement améliorer la lisibilité de votre code. Il aide le lecteur à comprendre visuellement comment votre code se divise en sections et comment ces sections sont liées les unes aux autres.

Longueur de ligne maximale et rupture de ligne

PEP 8 suggère que les lignes devraient être limitées à 79 caractères. En effet, cela vous permet d'ouvrir plusieurs fichiers côte à côte, tout en évitant le retour à la ligne.

Bien sûr, garder les déclarations à 79 caractères ou moins n'est pas toujours possible. PEP 8 décrit les moyens d'autoriser les instructions à s'exécuter sur plusieurs lignes.

Python assumera la continuation de la ligne si le code est contenu entre parenthèses, crochets ou accolades:

def function(arg_one, arg_two,
             arg_three, arg_four):
    return arg_one

S'il est impossible d'utiliser la continuation implicite, vous pouvez utiliser des barres obliques inverses pour rompre les lignes à la place:

from mypkg import example1, \
    example2, example3

Cependant, si vous pouvez utiliser la continuation implicite, vous devez le faire.

Si un saut de ligne doit se produire autour d'opérateurs binaires, comme+ et*, il doit se produire avant l'opérateur. Cette règle découle des mathématiques. Les mathématiciens conviennent que la rupture avant les opérateurs binaires améliore la lisibilité. Comparez les deux exemples suivants.

Voici un exemple de rupture devant un opérateur binaire:

# Recommended
total = (first_variable
         + second_variable
         - third_variable)

Vous pouvez immédiatement voir quelle variable est ajoutée ou soustraite, car l'opérateur est juste à côté de la variable en cours d'opération.

Voyons maintenant un exemple de rupture après un opérateur binaire:

# Not Recommended
total = (first_variable +
         second_variable -
         third_variable)

Ici, il est plus difficile de voir quelle variable est ajoutée et laquelle est soustraite.

La coupure avant les opérateurs binaires produit un code plus lisible, donc PEP 8 l'encourage. Le code queconsistently casse après un opérateur binaire est toujours conforme à PEP 8. Cependant, vous êtes encouragé à vous interrompre devant un opérateur binaire.

Échancrure

"Il devrait y avoir une - et de préférence une seule - façon évidente de le faire."

-The Zen of Python

L'indentation, ou premier espace blanc, est extrêmement importante en Python. Le niveau d'indentation des lignes de code en Python détermine comment les instructions sont regroupées.

Prenons l'exemple suivant:

x = 3
if x > 5:
    print('x is larger than 5')

L'instructionprint indentée indique à Python qu'elle ne doit être exécutée que si l'instructionif renvoieTrue. La même indentation s'applique pour indiquer à Python quel code exécuter lorsqu'une fonction est appelée ou quel code appartient à une classe donnée.

Les principales règles d'indentation établies par PEP 8 sont les suivantes:

  • Utilisez 4 espaces consécutifs pour indiquer l'indentation.

  • Préférez les espaces aux tabulations.

Onglets vs Les espaces

Comme mentionné ci-dessus, vous devez utiliser des espaces au lieu des tabulations lors de l'indentation du code. Vous pouvez ajuster les paramètres dans votre éditeur de texte pour générer 4 espaces au lieu d'un caractère de tabulation, lorsque vous appuyez sur la touche[.kbd .key-tab]#Tab #.

Si vous utilisez Python 2 et que vous avez utilisé un mélange d'onglets et d'espaces pour indenter votre code, vous ne verrez pas d'erreurs lorsque vous tenterez de l'exécuter. Pour vous aider à vérifier la cohérence, vous pouvez ajouter un indicateur-t lors de l'exécution de code Python 2 à partir de la ligne de commande. L'interprète émet des avertissements lorsque vous n'êtes pas cohérent avec votre utilisation des tabulations et des espaces:

$ python2 -t code.py
code.py: inconsistent use of tabs and spaces in indentation

Si, à la place, vous utilisez l'indicateur-tt, l'interpréteur émettra des erreurs au lieu d'avertissements et votre code ne fonctionnera pas. L'avantage d'utiliser cette méthode est que l'interpréteur vous indique où se trouvent les incohérences:

$ python2 -tt code.py
  File "code.py", line 3
    print(i, j)
             ^
TabError: inconsistent use of tabs and spaces in indentation

Python 3 ne permet pas de mélanger des tabulations et des espaces. Par conséquent, si vous utilisez Python 3, ces erreurs sont générées automatiquement:

$ python3 code.py
  File "code.py", line 3
    print(i, j)
              ^
TabError: inconsistent use of tabs and spaces in indentation

Vous pouvez écrire du code Python avec des tabulations ou des espaces indiquant une indentation. Mais, si vous utilisez Python 3, vous devez être cohérent avec votre choix. Sinon, votre code ne s'exécutera pas. PEP 8 vous recommande d'utiliser toujours 4 espaces consécutifs pour indiquer l'indentation.

Retrait après les sauts de ligne

Lorsque vous utilisez des continuations de ligne pour limiter les lignes à moins de 79 caractères, il est utile d'utiliser l'indentation pour améliorer la lisibilité. Il permet au lecteur de distinguer entre deux lignes de code et une seule ligne de code qui s'étend sur deux lignes. Il existe deux styles d'indentation que vous pouvez utiliser.

La première consiste à aligner le bloc en retrait sur le délimiteur d'ouverture:

def function(arg_one, arg_two,
             arg_three, arg_four):
    return arg_one

Parfois, vous pouvez constater que seulement 4 espaces sont nécessaires pour s'aligner avec le délimiteur d'ouverture. Cela se produira souvent dans les instructionsif qui s'étendent sur plusieurs lignes car lesif, l'espace et le crochet ouvrant constituent 4 caractères. Dans ce cas, il peut être difficile de déterminer où commence le bloc de code imbriqué dans l'instructionif:

x = 5
if (x > 3 and
    x < 10):
    print(x)

Dans ce cas, PEP 8 propose deux alternatives pour améliorer la lisibilité:

  • Ajoutez un commentaire après la condition finale. En raison de la coloration syntaxique dans la plupart des éditeurs, cela séparera les conditions du code imbriqué:

    x = 5
    if (x > 3 and
        x < 10):
        # Both conditions satisfied
        print(x)
  • Ajoutez une indentation supplémentaire sur la suite de la ligne:

    x = 5
    if (x > 3 and
            x < 10):
        print(x)

Un autre style d'indentation après un saut de ligne est unhanging indent. Il s'agit d'un terme typographique signifiant que chaque ligne, sauf la première d'un paragraphe ou d'une déclaration, est en retrait. Vous pouvez utiliser un tiret suspendu pour représenter visuellement une continuation d'une ligne de code. Voici un exemple:

var = function(
    arg_one, arg_two,
    arg_three, arg_four)

Note: lorsque vous utilisez un retrait suspendu, il ne doit y avoir aucun argument sur la première ligne. L'exemple suivant n'est pas conforme à PEP 8:

# Not Recommended
var = function(arg_one, arg_two,
    arg_three, arg_four)

Lorsque vous utilisez un retrait suspendu, ajoutez un retrait supplémentaire pour distinguer la ligne continue du code contenu dans la fonction. L'exemple suivant est difficile à lire car le code à l'intérieur de la fonction est au même niveau d'indentation que les lignes continues:

# Not Recommended
def function(
    arg_one, arg_two,
    arg_three, arg_four):
    return arg_one

Au lieu de cela, il vaut mieux utiliser un double retrait sur la suite de la ligne. Cela vous aide à faire la distinction entre les arguments de fonction et le corps de la fonction, améliorant la lisibilité:

def function(
        arg_one, arg_two,
        arg_three, arg_four):
    return arg_one

Lorsque vous écrivez du code compatible PEP 8, la limite de 79 caractères vous oblige à ajouter des sauts de ligne dans votre code. Pour améliorer la lisibilité, vous devez mettre en retrait une ligne continue pour montrer qu'il s'agit d'une ligne continue. Il y a deux façons de le faire. La première consiste à aligner le bloc en retrait avec le délimiteur d'ouverture. La seconde consiste à utiliser un tiret suspendu. Vous êtes libre de choisir la méthode d'indentation que vous utilisez après un saut de ligne.

Où mettre l'accolade de fermeture

Les continuations de ligne vous permettent de couper les lignes entre parenthèses, crochets ou accolades. Il est facile d'oublier l'accolade de fermeture, mais il est important de la placer dans un endroit sensé. Sinon, cela peut dérouter le lecteur. PEP 8 offre deux options pour la position de l'accolade fermante dans les suites de lignes implicites:

  • Alignez l'accolade de fermeture avec le premier caractère non blanc de la ligne précédente:

    list_of_numbers = [
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
        ]
  • Alignez l'accolade de fermeture avec le premier caractère de la ligne qui démarre la construction:

    list_of_numbers = [
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
    ]

Vous êtes libre de choisir l'option que vous utilisez. Mais, comme toujours, la cohérence est la clé, alors essayez de vous en tenir à l'une des méthodes ci-dessus.

"Si la mise en œuvre est difficile à expliquer, c'est une mauvaise idée."

-The Zen of Python

Vous devez utiliser des commentaires pour documenter le code tel qu'il est écrit. Il est important de documenter votre code afin que vous, et tout collaborateur, puissiez le comprendre. Lorsque vous ou quelqu'un d'autre lisez un commentaire, il doit être en mesure de comprendre facilement le code auquel le commentaire s'applique et comment il s'intègre au reste de votre code.

Voici quelques points clés à retenir lors de l'ajout de commentaires à votre code:

  • Limitez la longueur de ligne des commentaires et des docstrings à 72 caractères.

  • Utilisez des phrases complètes, en commençant par une majuscule.

  • Assurez-vous de mettre à jour les commentaires si vous modifiez votre code.

Utilisez des commentaires de bloc pour documenter une petite section de code. Ils sont utiles lorsque vous devez écrire plusieurs lignes de code pour effectuer une seule action, comme l'importation de données à partir d'un fichier ou la mise à jour d'une entrée de base de données. Ils sont importants car ils aident les autres à comprendre le but et la fonctionnalité d'un bloc de code donné.

PEP 8 fournit les règles suivantes pour écrire des commentaires de bloc:

  • Mettre en retrait les commentaires de bloc au même niveau que le code qu'ils décrivent.

  • Commencez chaque ligne par un# suivi d'un seul espace.

  • Séparez les paragraphes par une ligne contenant un seul#.

Voici un commentaire de bloc expliquant la fonction d'une bouclefor. Notez que la phrase passe à une nouvelle ligne pour conserver la limite de 79 caractères:

for i in range(0, 10):
    # Loop over i ten times and print out the value of i, followed by a
    # new line character
    print(i, '\n')

Parfois, si le code est très technique, il est nécessaire d'utiliser plus d'un paragraphe dans un commentaire de bloc:

def quadratic(a, b, c, x):
    # Calculate the solution to a quadratic equation using the quadratic
    # formula.
    #
    # There are always two solutions to a quadratic equation, x_1 and x_2.
    x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
    x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    return x_1, x_2

Si vous avez un doute sur le type de commentaire approprié, les commentaires bloqués sont souvent la solution. Utilisez-les autant que possible tout au long de votre code, mais assurez-vous de les mettre à jour si vous apportez des modifications à votre code!

Les commentaires en ligne expliquent une seule instruction dans un morceau de code. Ils sont utiles pour vous rappeler, ou expliquer aux autres, pourquoi une certaine ligne de code est nécessaire. Voici ce que PEP 8 a à dire à leur sujet:

  • Utilisez les commentaires en ligne avec parcimonie.

  • Écrivez des commentaires en ligne sur la même ligne que la déclaration à laquelle ils se réfèrent.

  • Séparez les commentaires en ligne par deux espaces ou plus de l'instruction.

  • Commencez les commentaires en ligne avec un# et un seul espace, comme les commentaires de bloc.

  • Ne les utilisez pas pour expliquer l'évidence.

Voici un exemple de commentaire en ligne:

x = 5  # This is an inline comment

Parfois, des commentaires en ligne peuvent sembler nécessaires, mais vous pouvez utiliser à la place de meilleures conventions de dénomination. Voici un exemple:

x = 'John Smith'  # Student Name

Ici, le commentaire en ligne donne des informations supplémentaires. Cependant, l’utilisation dex comme nom de variable pour le nom d’une personne est une mauvaise pratique. Vous n'avez pas besoin du commentaire en ligne si vous renommez votre variable:

student_name = 'John Smith'

Enfin, les commentaires en ligne tels que ceux-ci sont une mauvaise pratique car ils énoncent le code évident et encombrant:

empty_list = []  # Initialize empty list

x = 5
x = x * 5  # Multiply x by 5

Les commentaires en ligne sont plus spécifiques que les commentaires de bloc, et il est facile de les ajouter lorsqu'ils ne sont pas nécessaires, ce qui entraîne un encombrement. Vous pouvez vous en sortir en n'utilisant que des commentaires de bloc, donc, à moins que vous ne soyez sûr d'avoir besoin d'un commentaire en ligne, votre code est plus susceptible d'être conforme à PEP 8 si vous vous en tenez à bloquer les commentaires.

Chaînes de documentation

Les chaînes de documentation, ou docstrings, sont des chaînes entre guillemets doubles (""") ou simples (''') qui apparaissent sur la première ligne de toute fonction, classe, méthode ou module. Vous pouvez les utiliser pour expliquer et documenter un bloc de code spécifique. Il existe un PEP complet,PEP 257, qui couvre les docstrings, mais vous obtiendrez un résumé dans cette section.

Les règles les plus importantes s'appliquant aux docstrings sont les suivantes:

  • Entourez les docstrings de trois guillemets de chaque côté, comme dans"""This is a docstring""".

  • Écrivez-les pour tous les modules, fonctions, classes et méthodes publics.

  • Mettez le""" qui termine une docstring multiligne sur une ligne par lui-même:

    def quadratic(a, b, c, x):
        """Solve quadratic equation via the quadratic formula.
    
        A quadratic equation has the following form:
        ax**2 + bx + c = 0
    
        There always two solutions to a quadratic equation: x_1 & x_2.
        """
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2
  • Pour les docstrings sur une ligne, conservez les""" sur la même ligne:

    def quadratic(a, b, c, x):
        """Use the quadratic formula"""
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2

Pour un article plus détaillé sur la documentation du code Python, consultezDocumenting Python Code: A Complete Guide de James Mertz.

Espace dans les expressions et les déclarations

"Clairsemé vaut mieux que dense."

-The Zen of Python

Les espaces blancs peuvent être très utiles dans les expressions et les instructions lorsqu'ils sont utilisés correctement. S'il n'y a pas suffisamment d'espace, le code peut être difficile à lire, car il est tout regroupé. S'il y a trop d'espace, il peut être difficile de combiner visuellement les termes associés dans une déclaration.

Espace autour des opérateurs binaires

Entourez les opérateurs binaires suivants d'un espace unique de chaque côté:

  • Opérateurs d'affectation (=,+=,-=, etc.)

  • Comparaisons (==,!=,>,<. >=,<=) et (is,is not,in,not in)

  • Booléens (and,not,or)

Note: lorsque= est utilisé pour affecter une valeur par défaut à un argument de fonction, ne l'entourez pas d'espaces.

# Recommended
def function(default_parameter=5):
    # ...


# Not recommended
def function(default_parameter = 5):
    # ...

Lorsqu'il y a plusieurs opérateurs dans une instruction, l'ajout d'un seul espace avant et après chaque opérateur peut sembler déroutant. Au lieu de cela, il est préférable d'ajouter uniquement des espaces autour des opérateurs avec la priorité la plus faible, en particulier lors de la manipulation mathématique. Voici quelques exemples:

# Recommended
y = x**2 + 5
z = (x+y) * (x-y)

# Not Recommended
y = x ** 2 + 5
z = (x + y) * (x - y)

Vous pouvez également l'appliquer aux instructionsif où il existe plusieurs conditions:

# Not recommended
if x > 5 and x % 2 == 0:
    print('x is larger than 5 and divisible by 2!')

Dans l'exemple ci-dessus, l'opérateurand a la priorité la plus basse. Il peut donc être plus clair d'exprimer l'énoncéif comme suit:

# Recommended
if x>5 and x%2==0:
    print('x is larger than 5 and divisible by 2!')

Vous êtes libre de choisir ce qui est plus clair, avec la mise en garde que vous devez utiliser la même quantité d'espace blanc de chaque côté de l'opérateur.

Ce qui suit n'est pas acceptable:

# Definitely do not do this!
if x >5 and x% 2== 0:
    print('x is larger than 5 and divisible by 2!')

Dans les tranches, les deux-points agissent comme des opérateurs binaires. Par conséquent, les règles décrites dans la section précédente s'appliquent et il doit y avoir la même quantité d'espace blanc de chaque côté. Les exemples suivants de tranches de liste sont valides:

list[3:4]

# Treat the colon as the operator with lowest priority
list[x+1 : x+2]

# In an extended slice, both colons must be
# surrounded by the same amount of whitespace
list[3:4:5]
list[x+1 : x+2 : x+3]

# The space is omitted if a slice parameter is omitted
list[x+1 : x+2 :]

En résumé, vous devez entourer la plupart des opérateurs d'espaces. Cependant, il y a quelques mises en garde à cette règle, comme dans les arguments de fonction ou lorsque vous combinez plusieurs opérateurs dans une seule instruction.

Quand éviter d'ajouter un espace blanc

Dans certains cas, l'ajout d'espaces peut rendre le code plus difficile à lire. Trop d'espace blanc peut rendre le code trop clairsemé et difficile à suivre. PEP 8 donne des exemples très clairs où les espaces blancs sont inappropriés.

L'endroit le plus important pour éviter d'ajouter des espaces est à la fin d'une ligne. Ceci est connu sous le nom detrailing whitespace. Il est invisible et peut produire des erreurs difficiles à retracer.

La liste suivante décrit certains cas où vous devez éviter d'ajouter des espaces:

  • Immédiatement entre parenthèses, crochets ou accolades:

    # Recommended
    my_list = [1, 2, 3]
    
    # Not recommended
    my_list = [ 1, 2, 3, ]
  • Avant une virgule, un point-virgule ou deux points:

    x = 5
    y = 6
    
    # Recommended
    print(x, y)
    
    # Not recommended
    print(x , y)
  • Avant la parenthèse ouverte qui démarre la liste d'arguments d'un appel de fonction:

    def double(x):
        return x * 2
    
    # Recommended
    double(3)
    
    # Not recommended
    double (3)
  • Avant le crochet ouvert qui démarre un index ou une tranche:

    # Recommended
    list[3]
    
    # Not recommended
    list [3]
  • Entre une virgule de fin et une parenthèse fermante:

    # Recommended
    tuple = (1,)
    
    # Not recommended
    tuple = (1, )
  • Pour aligner les opérateurs d'affectation:

    # Recommended
    var1 = 5
    var2 = 6
    some_long_var = 7
    
    # Not recommended
    var1          = 5
    var2          = 6
    some_long_var = 7

Assurez-vous qu'il n'y a aucun espace de fin dans votre code. Il existe d'autres cas où PEP 8 décourage l'ajout d'espaces supplémentaires, tels que les parenthèses immédiatement à l'intérieur, ainsi qu'avant les virgules et les deux-points. Vous ne devez également jamais ajouter d'espace supplémentaire afin d'aligner les opérateurs.

Recommandations de programmation

"Simple vaut mieux que complexe."

-The Zen of Python

Vous constaterez souvent qu'il existe plusieurs façons d'effectuer une action similaire en Python (et tout autre langage de programmation d'ailleurs). Dans cette section, vous verrez certaines des suggestions fournies par PEP 8 pour lever cette ambiguïté et préserver la cohérence.

Don’t compare boolean values to True or False using the equivalence operator. Vous devrez souvent vérifier si une valeur booléenne est True ou False. Pour ce faire, il est intuitif de le faire avec une déclaration comme celle ci-dessous:

# Not recommended
my_bool = 6 > 5
if my_bool == True:
    return '6 is bigger than 5'

L'utilisation de l'opérateur d'équivalence,==, est ici inutile. bool ne peut prendre que les valeursTrue ouFalse. Il suffit d'écrire ce qui suit:

# Recommended
if my_bool:
    return '6 is bigger than 5'

Cette façon d'exécuter une instructionif avec un booléen nécessite moins de code et est plus simple, donc PEP 8 l'encourage.

Use the fact that empty sequences are falsy in if statements. Si vous voulez vérifier si une liste est vide, vous pourriez être tenté de vérifier la longueur de la liste. Si la liste est vide, sa longueur est0, ce qui équivaut àFalse lorsqu'il est utilisé dans une instructionif. Voici un exemple:

# Not recommended
my_list = []
if not len(my_list):
    print('List is empty!')

Cependant, en Python, toute liste, chaîne ou tuple vide estfalsy. Nous pouvons donc proposer une alternative plus simple à ce qui précède:

# Recommended
my_list = []
if not my_list:
    print('List is empty!')

Alors que les deux exemples afficherontList is empty!, la deuxième option est plus simple, donc PEP 8 l'encourage.

Use is not rather than not ... is in if statements. Si vous essayez de vérifier si une variable a une valeur définie, il existe deux options. La première consiste à évaluer une instructionif avecx is not None, comme dans l'exemple ci-dessous:

# Recommended
if x is not None:
    return 'x exists!'

Une deuxième option serait d'évaluerx is None, puis d'avoir une instructionif basée surnot le résultat:

# Not recommended
if not x is None:
    return 'x exists!'

Alors que les deux options seront évaluées correctement, la première est plus simple, donc PEP 8 l'encourage.

Don’t use if x: when you mean if x is not None:. Parfois, vous pouvez avoir une fonction avec des argumentsNone par défaut. Une erreur courante lors de la vérification si un tel argument,arg, a reçu une valeur différente est d'utiliser ce qui suit:

# Not Recommended
if arg:
    # Do something with arg...

Ce code vérifie quearg est véridique. Au lieu de cela, vous voulez vérifier quearg estnot None, il serait donc préférable d'utiliser ce qui suit:

# Recommended
if arg is not None:
    # Do something with arg...

L'erreur commise ici est de supposer quenot None et la vérité sont équivalents. Vous auriez pu définirarg = []. Comme nous l'avons vu ci-dessus, les listes vides sont évaluées comme fausses en Python. Ainsi, même si l'argumentarg a été assigné, la condition n'est pas remplie, et donc le code dans le corps de l'instructionif ne sera pas exécuté.

Use .startswith() and .endswith() instead of slicing. Si vous essayiez de vérifier si une chaîneword était préfixée, ou suffixée, avec le motcat, il peut sembler judicieux d'utiliserlist slicing. Cependant, le découpage de liste est sujet à erreur et vous devez coder en dur le nombre de caractères dans le préfixe ou le suffixe. Il n'est également pas clair pour quelqu'un moins familier avec la liste Python de découper ce que vous essayez de réaliser:

# Not recommended
if word[:3] == 'cat':
    print('The word starts with "cat"')

Cependant, ce n'est pas aussi lisible que l'utilisation de.startswith():

# Recommended
if word.startswith('cat'):
    print('The word starts with "cat"')

De même, le même principe s'applique lorsque vous recherchez des suffixes. L'exemple ci-dessous décrit comment vous pouvez vérifier si une chaîne se termine parjpg:

# Not recommended
if file_name[-3:] == 'jpg':
    print('The file is a JPEG')

Bien que le résultat soit correct, la notation est un peu maladroite et difficile à lire. Au lieu de cela, vous pouvez utiliser.endswith() comme dans l'exemple ci-dessous:

# Recommended
if file_name.endswith('jpg'):
    print('The file is a JPEG')

Comme pour la plupart de ces recommandations de programmation, l'objectif est la lisibilité et la simplicité. En Python, il existe de nombreuses façons différentes d'effectuer la même action, donc les directives sur les méthodes à choisir sont utiles.

Quand ignorer PEP 8

La réponse courte à cette question n'est jamais. Si vous suivez PEP 8 à la lettre, vous pouvez garantir que vous disposerez d'un code propre, professionnel et lisible. Cela profitera à vous ainsi qu'aux collaborateurs et aux employeurs potentiels.

Cependant, certaines directives de PEP 8 ne sont pas pratiques dans les cas suivants:

  • Si se conformer à PEP 8 romprait la compatibilité avec les logiciels existants

  • Si le code entourant ce sur quoi vous travaillez est incompatible avec PEP 8

  • Si le code doit rester compatible avec les anciennes versions de Python

Trucs et astuces pour vous assurer que votre code respecte PEP 8

Il y a beaucoup à retenir pour vous assurer que votre code est conforme à PEP 8. Il peut être difficile de se souvenir de toutes ces règles lorsque vous développez du code. Il est particulièrement long de mettre à jour des projets antérieurs pour qu'ils soient conformes à PEP 8. Heureusement, il existe des outils qui peuvent aider à accélérer ce processus. Il existe deux classes d'outils que vous pouvez utiliser pour appliquer la conformité PEP 8: les linters et les autoformatters.

Linters

Les linters sont des programmes qui analysent les erreurs de code et d'indicateur. Ils fournissent des suggestions sur la façon de corriger l'erreur. Les linters sont particulièrement utiles lorsqu'ils sont installés en tant qu'extensions de votre éditeur de texte, car ils signalent les erreurs et les problèmes stylistiques lors de l'écriture. Dans cette section, vous verrez un aperçu du fonctionnement des linters, avec des liens vers les extensions de l'éditeur de texte à la fin.

Les meilleurs linters pour le code Python sont les suivants:

  • pycodestyle est un outil pour vérifier votre code Python par rapport à certaines des conventions de style de PEP 8.

    Installezpycodestyle en utilisantpip:

    $ pip install pycodestyle

    Vous pouvez exécuterpycodestyle depuis le terminal à l'aide de la commande suivante:

    $ pycodestyle code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:6:19: E711 comparison to None should be 'if cond is None:'
  • flake8 est un outil qui combine un débogueur,pyflakes, avecpycodestyle.

    Installezflake8 en utilisantpip:

    $ pip install flake8

    Exécutezflake8 depuis le terminal à l'aide de la commande suivante:

    $ flake8 code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:3:17: E999 SyntaxError: invalid syntax
    code.py:6:19: E711 comparison to None should be 'if cond is None:'

    Un exemple de la sortie est également montré.

Note: la ligne supplémentaire de sortie indique une erreur de syntaxe.

Ils sont également disponibles en tant qu'extensions pourAtom,Sublime Text,https://code.visualstudio.com/docs/python/linting#flake8[Visual Studio Code], and VIM. You can also find guides on setting up Sublime Text and VIM for Python development, as well as an overview of some popular text editors at _Real Python.

Formats automatiques

Les formats automatiques sont des programmes qui remanient votre code pour qu'il se conforme automatiquement à PEP 8. Une fois que ce programme estblack, qui autoformate le code suivantmost des règles de PEP 8. Une grande différence est qu'il limite la longueur de ligne à 88 caractères plutôt qu'à 79. Cependant, vous pouvez remplacer cela en ajoutant un indicateur de ligne de commande, comme vous le verrez dans un exemple ci-dessous.

Installezblack en utilisantpip. Il nécessite Python 3.6+ pour fonctionner:

$ pip install black

Il peut être exécuté via la ligne de commande, comme avec les linters. Supposons que vous commenciez avec le code suivant qui n’est pas conforme à PEP 8 dans un fichier appelécode.py:

for i in range(0,3):
    for j in range(0,3):
        if (i==2):
            print(i,j)

Vous pouvez ensuite exécuter la commande suivante via la ligne de commande:

$ black code.py
reformatted code.py
All done! ✨ 🍰 ✨

code.py sera automatiquement reformaté pour ressembler à ceci:

for i in range(0, 3):
    for j in range(0, 3):
        if i == 2:
            print(i, j)

Si vous souhaitez modifier la limite de longueur de ligne, vous pouvez utiliser l'indicateur--line-length:

$ black --line-length=79 code.py
reformatted code.py
All done! ✨ 🍰 ✨

Deux autres autoformateurs,autopep8 etyapf, exécutent des actions similaires à celles deblack.

Un autre tutoriel deReal Python,Python Code Quality: Tools & Best Practices d'Alexander van Tol, explique en détail comment utiliser ces outils.

Conclusion

Vous savez maintenant comment écrire du code Python de haute qualité et lisible en utilisant les directives énoncées dans PEP 8. Bien que les directives puissent sembler pédantesques, les suivre peut vraiment améliorer votre code, en particulier lorsqu'il s'agit de partager votre code avec des employeurs ou des collaborateurs potentiels.

Dans ce didacticiel, vous avez appris:

  • Qu'est-ce que PEP 8 et pourquoi il existe

  • Pourquoi vous devriez viser à écrire du code conforme à PEP 8

  • Comment écrire du code compatible PEP 8

En plus de tout cela, vous avez également vu comment utiliser les linters et les formats automatiques pour comparer votre code avec les directives PEP 8.

Si vous voulez en savoir plus sur PEP 8, alors vous pouvez lire lesfull documentation, ou visiterpep8.org, qui contient les mêmes informations mais a été bien formaté. Dans ces documents, vous trouverez le reste des directives PEP 8 non couvertes par ce tutoriel.