Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Style de code et conventions

Make your code consistent through style conventions. For interactive reading and executing code blocks Binder and find b08-pystyle.ipynb, or install Python and JupyterLab locally.

Respirez profondément, décollez et regardez ce que vous avez appris si loin d’une nouvelle perspective. Après ce chapitre, il sera utile d’avoir un autre regard sur votre ancien code et de le formater avec robustesse. Les lignes directrices de style présentées ici vont au-delà de l’esthétique visuelle et aident à écrire un code efficace.

incubate to solve Python programming problems

Historique et PPE-TSE

Ce guide de style met en lumière des parties du PEP 8 - Guide de style pour Python Code par Guido van Rossum, Barry Varsovie et Nick Coghlan. Le document complet est disponible à python.org et seuls les aspects pertinents pour les applications présentées dans ce livre électronique sont présentés dans ce chapitre.

Qu’est-ce que PEP? PEP signifie Python Enhancement Proposals, dans lequel les développeurs de Python communiquent les fonctionnalités et les développements de Python. Il y a plusieurs milliers de PEP, couvrant les fonctions linguistiques proposées, les versions de bug-fix, les processus et les guides de style (lisez la liste complète et actuelle des PEP à python.org). Cette section présente les recommandations énoncées dans PEP 8, le guide de style pour le code Python.

De nombreux IDE, y compris PyCharm ou VS Code, fournissent une auto-complétion et des outils avec des conseils de style PEP pour faciliter une programmation cohérente. Ainsi, lorsque votre IDE souligne quelque chose dans votre script, vérifiez la raison de cela et envisagez de modifier le code en conséquence.

Le Zen de Python

On devient spirituels ? Loin de là. Le Zen de Python est une information PEP (20) de Tim Peters pour guider les programmeurs. Il s’agit de quelques lignes résumant les bonnes pratiques en matière de codage. Python Egg import this imprime le Zen de Python dans n’importe quel interprète Python :

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Définition du code

Longueur maximale de la ligne

La longueur maximale d’une ligne est de 79 caractères et les commentaires en ligne, y compris docstrings, ne doivent pas dépasser 72 caractères.

Indication

L’identification désigne le déplacement du code (blocs) vers la droite. L’identification est nécessaire, par exemple, en boucles ou en fonctions pour attribuer des blocs de code à une déclaration for ou def. Dans un sens plus large, les indentations représentent des espaces de noms, où les variables locales définies dans la région dentelée ne sont valables qu’ici. Plusieurs niveaux d’indentation se produisent lorsque des instructions imbriquées sont utilisées (p. ex., une condition if imbriquée dans une boucle for). Un niveau d’indentation correspond à 4 espaces.

for i in range(1,2):
    print("I'm one level indented.")
    if i == 1:
        print("I'm two levels indented.")
I'm one level indented.
I'm two levels indented.

Parce que les longues lignes de code sont de mauvaises pratiques, nous devons parfois utiliser les pauses de ligne lors de l’attribution d’une list ou de l’appel d’une fonction. Dans ces cas, la prochaine ligne continue est également insérée et il y a différentes options pour les cessions multilignes. Ici, nous voulons utiliser le code de style d’utiliser un délimiteur d’ouverture pour l’indentation:

a_too_long_word_list = ["Do", "not", "hard-code", "something", "like", "this.",
                        "There", "are", "better", "ways."]
a_better_indented_list = [
    "Do",
    "not",
    "hard-code",
    "something",
    "like",
    "this.",
    "...",
    ]

Rappel : PyCharm, VS Code et beaucoup d’autres IDE mettent automatiquement en page l’indentation.

Pause de ligne des expressions avec les opérateurs binaires

Lorsque les opérateurs binaires font partie d’une expression qui dépasse la longueur maximale de la ligne de 79 caractères, la rupture de ligne doit être devant les opérateurs binaires.

import pandas as pd

dummy_df = pd.get_dummies(pd.Series(['variable1', 'parameter2', 'sensor3']), dtype=int)
print(dummy_df.head(3))

dum_sum = (dummy_df['variable1']
           + dummy_df['parameter2']
           - dummy_df['sensor3'])
   parameter2  sensor3  variable1
0           0        0          1
1           1        0          0
2           0        1          0

Lignes blanches

Pour séparer les blocs de code, appuyez plusieurs fois sur la touche Enter. Cependant, l’utilisation aléatoire et motivée par l’humeur de lignes blanches entraîne un code non structuré. C’est pourquoi PEP 8 auteurs fournissent également des conseils sur l’utilisation de lignes blanches:

  • Définition des classes surround et fonctions de haut niveau (c.-à-d. fonctions où la ligne def-line n’est pas dentelée) avec deux lignes blanches.

  • Méthodes surround (p. ex. fonctions dans une classe) avec une ligne vide.

  • Utilisez des lignes blanches dans tous les autres codes pour indiquer les sections logiques.

# blank 1 before top-level function
# blank 2 before top-level function
def top_level_function():
    pass
# blank 1 after top-level function
# blank 2 after top-level function

Blancs (espaces blancs)

Les espaces blancs aident à détendre la disposition du code, mais trop de espaces blancs doivent être évités comme par exemple:

  • Entre parenthèses, entre parenthèses ou accessoires (non : list( e1, e2 ) vs oui : list(e1, e2))

  • Entre parenthèses avec des virgules traînantes (non: a_tuple = (1, ) vs. oui: a_tuple = (1,))

  • Immédiatement avant une virgule

  • Entre le nom de la fonction et les parenthèses de l’argument (non: fun (arg) vs. yes: fun(arg)) et similaire pour les éléments de liste ou de dictionnaire

  • Autour du signe = des paramètres de fonction non annotés indiquant une valeur par défaut (non: def fun(arg = 0.0) vs. oui: def fun(arg=0.0))

  • Avant : sauf entre parenthèses ou entre parenthèses, suivre le : (par exemple, a_dict = {a_key: a_value})

Les espaces blancs doivent être ajoutés:

  • Autour de tout opérateur, booléen ou (augmenté) affectation (par exemple, ==, <, >, !=, <=, >=, in, not in, is, is not, and, or, not, +=, -=)

  • Après les colonnes : si une valeur précède le : et qu’aucune parenthèses ou entre parenthèses ne suit immédiatement le : (par exemple, a_dict = {a_key: a_value})

Paquets et modules

importations

Les importations sont en haut du script, juste après tout commentaire docstrings ou autre module. Importer les bibliothèques d’abord, puis les paquets tiers, et enfin les modules ( propres) stockés localement. Utiliser de préférence les importations absolues (p. ex., import package.module ou from package import module) et éviter les importations de wildcard (from module import *). Chaque importation devrait avoir sa propre ligne et éviter d’utiliser le signe virgule pour les importations multiples:

# DO:
import os
import numpy as np
# DO NOT:
import os, sys

Nommer les paquets et les scripts

Les nouveaux paquets ou modules personnalisés devraient avoir des noms courts et des noms minuscules, où les points forts peuvent être utilisés pour améliorer la lisibilité (découragés pour les paquets).

Commentaires

Bloc et commentaires en ligne

Les commentaires de bloc commencent par un seul # à la première place d’une ligne, suivi d’un espace blanc et du texte des commentaires.

Les commentaires en ligne suivent une expression et sont insérés dans deux espaces blancs. Cependant, les commentaires en ligne doivent être utilisés avec parcimonie.

Doctrines

Docstrings sont de courtes descriptions de texte dans un module, une fonction, une classe ou une méthode avec des spécifications d’arguments, d’utilisation et de sortie. Lors de l’instantanement d’un objet standard, ou du référencement d’une méthode de classe, l’attribut __doc__ imprimera l’information docstring de l’objet. Par exemple:

a_list = [1, 2]
print(a_list.__doc__)
Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list.
The argument must be an iterable if specified.

Lors de l’écriture d’une fonction Python, les docstrings sont introduits immédiatement après la ligne def ... avec triple double apostrophes:

def let_there_be_light(*args, **kwargs):
    """
    Bright function accepting any input argument with indifferent behavior.
    :param an_input_argument: STR or anything else
    :param another_input_argument: FLOAT or anything else
    :return: True (in all cases)
    """
    print("Sunrise")
    return True

print(let_there_be_light.__doc__)

    Bright function accepting any input argument with indifferent behavior.
    :param an_input_argument: STR or anything else
    :param another_input_argument: FLOAT or anything else
    :return: True (in all cases)
    

Notez que les recommandations sur les docstrings sont fournies avec PEP 257 plutôt que PEP 8.

Conventions sur les noms

Définition des styles de dénomination

Les conventions de nommage utilisent les styles suivants (source: python.org):

  • b (lettre en minuscules)

  • B (lettre majuscule unique)

  • lowercase

  • lower_case_with_underscores

  • UPPERCASE

  • UPPER_CASE_WITH_UNDERSCORES

  • CamelCase or CapWords or CapitalizedWords or StudlyCaps.
    Note: When using acronyms in CapWords, capitalize all the letters of the acronym (e.g., HTTPResponse is better than HttpResponse).

  • mixedCase (differs de CapitalizedWords par caractère initial minuscule!)

  • Capitalized_Words_With_Underscores (déprécié)

Certains formats de noms variables déclenchent un comportement particulier de Python:

  • Les variables _single_leading_underscore indiquent une faible utilisation interne et ne seront pas importées avec from module import *

  • __double_leading_underscore les variables invoquent le nom mengling dans les classes (par exemple, une méthode appelée __dlu de la classe MyClass sera manggé dans _MyClass__dlu)

  • __double_leading_and_trailing_underscore__ variables sont magic objets ou attributs dans les espaces de noms contrôlés par l’utilisateur (par exemple, __init__ ou __call__ dans les classes)
    Utilisez seulement des attributs magiques documentés et ne les inventez jamais. En savoir plus sur les méthodes magiques dans le chapitre sur Python classes.

  • Les variables single_trailing_underscore_ sont utilisées pour éviter les conflits avec les mots clés Python (par exemple, MyClass(class_='AnotherClass'))

Noms des objets

Utilisez les styles définis ci-dessus pour nommer les éléments Python comme suit :

  • Classes : CamelCase (CapWords) lettres seulement comme MyClass

  • Constantes: UPPERCASE lettres seulement, où les soulignés peuvent améliorer la lisibilité (p. ex., utiliser à un niveau de module par exemple pour attribuer la densité d’eau RHO = 1000)

  • Exceptions : CamelCase (CapWords) lettres seulement (les exceptions doivent être prédéfinies classes Error; généralement utiliser le suffixe Error (par exemple, TypeError)

  • Fonctions: lowercase lettres seulement, où les accents peuvent améliorer la lisibilité; parfois mixedCase applique pour assurer la compatibilité en arrière des styles dominants

  • Méthodes (fonction de classe, non-public): _lowercase lettres seulement avec un point fort, où les points forts peuvent améliorer la lisibilité

  • Méthodes (fonction de classe, public): lowercase lettres seulement, où les accents peuvent améliorer la lisibilité

  • Modules : lowercase lettres seulement, où les accents peuvent améliorer la lisibilité

  • Packages: lowercase lettres seulement, où les accents sont découragés

  • Variables: lowercase lettres seulement, où les accents peuvent améliorer la lisibilité

  • Variables (global): lowercase lettres seulement, où les soulignés peuvent améliorer la lisibilité; notez que “global” devrait limiter à l’utilisation variable dans un seul module.

Autres recommandations de style de code

Pour assurer la compatibilité du code et l’efficacité du programme, le guide de style PEP 8 fournit d’autres recommandations générales (lire la suite dans le Python docs):

  • Lors de la définition d’une fonction, préférez les déclarations def plutôt que les expressions lambda, qui sont raisonnables pour une utilisation unique seulement

  • Lorsque des exceptions sont prévues, utilisez try - except clauses (voir la section errors and exceptions)

  • Assurez-vous que les méthodes et les fonctions renvoient les objets de façon uniforme, par exemple :

def a_function_with_return(x):
    if x > 0:
        return np.sqrt(x)
    else:
        return np.nan

Vérification de la réussite en apprentissage

Prenez le test de réussite d’apprentissage pour ce carnet Jupyter.