Guide de Style Python

Auteur: Guido Van Rossum
Traduction française: Régis Leroy, relecture: Odile Bénassy

Notes de traduction:

  Le document originel n'est pas complètement terminé, c'est la raison pour laquelle certains passages sont remplacés par des XXX.

XXX Intro

Une Sotte Cohérence est l'Epouvantail des Esprit Etroits.

Un guide de style traite de cohérence. La cohérence par rapport à ce guide de style est importante. Elle est plus importante encore pour un projet, et devient vitale à l'intérieur d'un module ou d'une fonction.

Mais le plus important: Sachez être parfois incohérent -- quelquefois ce guide de style ne s'applique tout simplement pas. Quand vous avez un doute, faites confiance à votre bon sens. Regardez d'autres exemples et décidez de ce qui est le mieux. Et n'hésitez pas à demander!

Index:

Mise en Page

L'Indentation

Utilisez la configuration par défaut du mode Python de Emacs: 4 espaces pour un niveau d'indentation. Pour le code vraiment très ancien où ne voulez pas semer la pagaille, vous pouvez continuer à utiliser 8 espaces. Dans ce cas, ajoutez la bidouille Emacs appropriée à la fin:

# Local Variables:
# py-indent-offset: 8
# End:

Tabulations ou Espaces ?

Un niveau d'indentation équivaut à 4 espaces, deux niveaux une tabulation, trois niveaux une tabulation et 4 espaces, et ainsi de suite. Python ne s'occupe pas de savoir si vous indentez une ligne avec 8 espaces et la suivante avec une tabulation -- elles sont considérées comme ayant la même indentation. Remplacer toutes les tabulations par des espaces est plus robuste si l'on en juge par ce qui se passe sur certains éditeurs sur Mac ou PC (qui, par défaut, affichent le caractère tabulation comme 4 espaces au lieu de 8, ce qui était la volonté de Dieu ) mais on peut faire la transformation lors du transfert vers ces plates-formes.

La Longueur Maximale des Lignes

Il y a encore beaucoup de consoles un peu partout qui sont limitées à des lignes de 80 caractères. La césure (coupure de ligne) par défaut des lignes sur ces systèmes donne un résultat affreux. Par conséquent, limitez s'il vous plaît toutes les lignes à un maximum de 79 caractères (Emacs coupe les lignes longues d'exactement 80 caractères).

Le meilleur moyen de gérer la césure des longues lignes est d'utiliser la continuation de ligne implicite de Python à l'intérieur de parenthèses, crochets et accolades. Si nécessaire, vous pouvez ajouter une paire de parenthèses supplémentaire autour d'une expression, mais quelquefois l'utilisation du backslash (oblique gauche \) semble meilleure.  Assurez-vous d'indenter la ligne continuée de manière appropriée. Le mode python d'Emacs fait cela très bien. Quelques exemples:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if width == 0 and height == 0 and \
           color == 'red' and emphasis == 'strong' or \
           highlight > 100:
            raise ValueError, "sorry, you lose"
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError, "I don't think so"
        Blob.__init__(self, widt, height,
                      color, emphasis, highlight)

Les Sauts de Lignes

Séparez les fonctions de niveau supérieur et les définitions de classes par deux sauts de lignes, et les définitions de méthodes à l'intérieur d'une classe par un seul saut de ligne. Vous pouvez utiliser (modérément) des sauts de lignes supplémentaires pour séparer des groupes de fonctions apparentées. Vous pouvez omettre des sauts de ligne à l'intérieur d'une grappe de 'une-ligne' apparentées (par exemple un jeu de maquettes d'implémentations).

Quand des sauts de lignes sont utilisés pour séparer les définitions de méthodes, il faut aussi une ligne blanche entre la ligne de 'classe' et la première définition de méthode.

Utilisez, avec modération, les sauts de lignes dans les fonctions pour indiquer les sections logiques.

Les Espaces dans les Expressions et Déclarations

Pet Peeves

Je déteste les espaces aux endroits suivants: (Ne vous embêtez pas à argumenter avec moi d'un quelconque de ces point -- Je suis accro à ce style depuis plus de 15 ans.)

Autres Recommandations

Commentaires

Des commentaires qui contredisent le code sont pires que pas de commentaires du tout. Faites-vous toujours une priorité de garder les commentaires à jour quand le code change!

Si un commentaire est constitué d'une proposition ou d'une phrase, le premier mot devrait commencer par une majuscule, à moins qu'il ne s'agisse d'un identifiant qui commence par une lettre minuscule (ne modifiez jamais la casse des identifiants!).

Si le commentaire est court, le point final est omis de préférence. Les blocs de commentaires consistent généralement en un ou plusieurs paragraphes construits à partir de phrases complètes, et chacune devrait se terminer par un point.

Vous pouvez utiliser deux espaces après un point terminant une phrase [NDT: règle syntaxique anglaise].

Comme toujours quand on écrit en anglais, "Strunk and White" s'applique [NDT:Strunk and White est un manuel de grammaire]

Pour les programmeurs Python venant de pays non-anglophones: s'il vous plaît écrivez vos commentaires en anglais, à moins que vous ne soyez sûrs à 120% que votre code ne sera jamais lu par des gens ne parlant pas votre langue.

Les Blocs de Commentaires.

Les blocs de commentaires s'appliquent généralement à une partie (ou à l'ensemble) du code qui les suit, et s'indentent au même niveau que ce code. Chaque ligne d'un bloc de commentaires débute avec un # suivi d'un seul espace (sauf s'il s'agit de texte indenté à l'intérieur du commentaire). les paragraphes à l'intérieur d'un bloc de commentaires sont séparés par une ligne contenant un seul #. La meilleure façon d'encadrer les blocs de commentaires consiste à insérer une ligne en-dessous et au-dessus d'eux (ou deux lignes au-dessus et une seule en-dessous pour un bloc de commentaires au début d'une nouvelle section de définitions de fonctions).

Commentaire En Ligne (Inline).

Un commentaire en ligne est un commentaire qui fait suite à une déclaration, sur la même ligne. Les commentaires en lignes doivent être utilisés avec parcimonie. Ils doivent être séparés de la déclaration par au moins deux espaces, et débuter par le signe # suivi d'un unique espace.

Les commentaires en ligne ne sont pas nécessaires et sont en fait un facteur de distraction s'ils expliquent l'évidence. N'écrivez pas:

x = x+1 # Incrémente x
Mais quelquefois, il est utile d'écrire:
x = x+1 # Compensation pour le bord

Les Chaînes de Documentation

Tous les modules devraient normalement avoir des chaînes de documentation, et toutes les fonctions et les classes exportées par un module devraient aussi avoir des chaînes de documentation. Enfin les méthodes publiques (y compris le constructeur __init__) devraient suivre la même règle.

La chaîne de documentation d'un script (un programme autonome) devrait être utilisable aussi en tant que message "d'usage", affiché quand le script est invoqué avec des arguments incorrects ou manquants (ou peut-être avec l'option "-h", pour "help"). Cette chaîne de documentation devrait documenter la fonction du script et la syntaxe de la ligne de commande, des variables d'environnement et des fichiers. Les message d'usage peuvent être assez élaborés (plusieurs écrans pleins). Ils devraient permettre aux nouveaux utilisateurs d'utiliser la commande correctement et fournir aux utilisateurs avancés une référence complète de toutes les options et arguments.

Pour la cohérence, utilisez toujours des """triples doubles guillemets""" autour des chaînes de documentation.

Il y a deux types de chaînes de documentation: les chaînes de documentation une-ligne et multi-lignes.

Les Chaînes de Documentation 'Une-ligne'

Les 'une-lignes' sont à réserver pour les cas vraiment évidents. Elles devraient réellement tenir sur une ligne. Par exemple:
def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
    ...
[NDT en français: """ Renvoie le chemin d'accès au répertoire racine de KOS"""]
Notes:

Chaînes de Documentation Multi-Lignes

 Les chaînes de documentation multi-lignes sont constituées d'une ligne de résumé comme s'il s'agissait d'une chaîne de documentation 'une-ligne', suivie par un saut de ligne et d'une description plus élaborée. La ligne de résumé est utilisée par les outils d'indexage automatique;: il est important qu'elle tienne sur une ligne et qu'elle soit séparée du reste par une ligne blanche.

 L'ensemble de la chaîne de documentation s'indente de la même manière que les guillemets de la première ligne (voir l'exemple ci-dessous). Les outils de traitement des chaînes de documentation devront ôter une certaine quantité d'indentation à partir de la seconde ligne et pour les lignes suivantes de cette documentation égale à l'indentation de la première ligne non blanche après la première ligne de la documentation. L'indentation relative des lignes suivantes de la chaîne de documentation est à conserver.

 Je recommande l'insertion une ligne blanche entre le dernier paragraphe d'une chaîne de documentation multi-ligne et ses guillemets fermants, ce qui place les guillemets fermants tout seuls sur leur ligne. De cette façon, la commande d'Emacs de remplissage de paragraphes fonctionnera.

 Je recommande aussi l'insertion d'une ligne blanche avant et après toutes les chaînes de documentation (une-ligne ou multi-lignes) qui documentent une classe -- d'une façon générale, les méthodes de la classe sont séparées entre elles par une seule ligne blanche, et la chaîne de documentation a besoin d'être décalée par rapport à la première méthode par une ligne blanche; pour la symétrie, je préfère avoir une ligne blanche entre l'entête de la classe et la documentation. Les chaînes de documentation documentant les fonctions n'ont généralement pas ces exigences, à moins que le corps de la fonction ne soit écrit comme un certain nombre de sections séparées par des sauts de lignes -- dans ce cas, traitez la documentation comme une autre section, et faites la précéder d'une ligne blanche.

 La chaîne de documentation d'un module devrait généralement lister les classes, exceptions et fonctions (et tout autres objets) qui sont exportés par le module, avec un résumé d'une ligne pour chacun. (Ces résumés donnent généralement moins de détails que la ligne de résumé de la chaîne de documentation de l'objet.)

La chaîne de documentation d'une fonction ou méthode devrait résumer sont comportement et documenter ses arguments, ses valeurs de retour, ses effets de bord, les exceptions levées, et les conditions pour son appel (tout ceci le cas échéant). Les arguments optionnels devraient être indiqués. Le fait que les arguments mots-clé soient ou non une partie de l'interface devrait lui aussi être documenté.

 La chaîne de documentation d'une classe devrait résumer son comportement et lister les méthodes publiques et variables d'instance. Si la classe est prévue pour être héritée, et possède une interface additionnelle pour les sous-classes, cette interface devrait être listée séparément (dans la chaîne de documentation). Le constructeur de la classe devrait être documenté dans la chaîne de documentation pour sa méthode __init__. Les méthodes individuelles devraient être documentées par leur propre chaîne de documentation.

 Si une classe hérite d'une autre classe et que son comportement est globalement analogue à celui de cette classe, sa chaîne de documentation devrait le mentionner et résumer les différences. Utilisez le verbe "override" [NDT: surcharger] pour indiquer que cette méthode héritée remplace une méthode de la superclasse sans appeller la méthode de superclasse; utilisez le verbe "extend" [NDT: étendre] pour indiquer que la méthode de héritée appelle la méthode de la superclasse (en plus de son propre comportement).

 N'utilisez pas la convention d'Emacs de mention des arguments des fonctions ou méthodes en majuscule dans le texte courant. Python est sensible à la casse et les noms d'arguments peuvent être utilisés comme des arguments mots-clés;, donc la chaîne de documentation devrait documenter les noms d'arguments exacts. Il est préférable de lister chaque argument sur une ligne séparée, et de séparer par deux signes moins le nom de l'argument de sa description, comme ci-dessous:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Traçabilité des Versions

Si vous devez absolument conserver un déchet de RCS ou CVS dans votre fichier source, faites-le ainsi :
__version__ = "$Revision: 1.3 $"
# $Source: /home/guido/ftp/pub/www.python.org/doc/essays/RCS/styleguide.html,v $
Ces lignes devraient être ajoutée à la suite de la chaîne de documentation du module, avant n'importe quel autre code, séparé par un saut de ligne au-dessus et en-dessous.

Conventions de Nommage

Les conventions de nommage de la librairie Python sont un peu en désordre, ce qui fait que nous n'auront jamais un ensemble complètement cohérent -- néanmoins, voici quelques lignes directrices.

Descriptif: Styles de Nommage

Il y a beaucoup de styles de nommage différents. C'est plus facile quand on peut reconnaître le type de nommage utilisé, indépendamment de la chose à laquelle il s'applique. On distingue habituellement les styles de nommage suivants:  Il y a aussi le style qui utilise un unique court préfixe pour grouper des noms reliés ensemble. Ce style n'est pas très utilisé en Python, mais je le mentionne pour être complet. Par exemple, la fonction os.stat() retourne un tuple dont les éléments ont traditionnellement des noms comme st_mode, st_size, st_mtime, etc. La librairie X11 met un grand X au début de toutes ses fonctions publiques. (En Python, ce style n'est généralement pas considéré comme nécessaire car les noms d'attributs et de méthodes sont préfixés par un objet, et les noms de fonction sont préfixés par un nom de module.)

 De plus, les formes spéciales suivantes utilisant des soulignés en tête ou à la fin sont reconnues (elles peuvent généralement se combiner avec n'importe quelle convention de nommage):

Prescription: Conventions de Nommage

Les Noms de Modules

Les noms de modules peuvent être soit en MotsCapitalisés, soit en minuscules. Il n'y a pas de convention non-ambiguë pour décider du style à utiliser. Les modules qui exportent une simple classe (ou un nombre de classes en relations proches, plus un support additionnel) sont souvent en MotsCapitalisés en reprenant le nom de la classe (par exemple le module standard StringIO). Les modules qui exportent un bouquet de fonctions sont souvent nommés complètement en minuscules.

 Comme les noms de modules sont projetés sur les noms de fichiers et que certains systèmes de fichiers, insensibles à la casse, tronquent les noms longs, il est important que les noms de modules soient raisonnablement courts afin de ne pas entrer en conflit avec d'autres noms de modules qui diffèreraient seulement par la casse -- ceci ne sera pas un problème sur Unix, mais en deviendra un quand le code sera transporté sur mac ou Windows.

 Il y a une convention naissante qui dit que lorsqu'un module d'extension écrit en C ou en C++ est accompagné d'un module Python qui procure une interface de plus haut niveau (par exemple plus orientée objet), le nom du module Python est un MotCapitalisé tandis que le nom du module C/C++ est entièrement en minuscules avec un souligné devant (par exemple Tkinter/_tkinter).

 Les "Paquetages" [NDT: "Packages" en anglais](groupes de modules, supportés par le module "ni") ont généralement un nom court entièremement en minuscules.

Les Noms de Classes

Quasiment sans exception, les noms de classes utilisent la convention MotCapitalisé. Les classes destinées à un usage interne possèdent de plus un souligné en tête.

Les Noms des Exceptions

Si un module définit une unique exception levée pour toutes sortes de conditions, elle est généralement appelée "error" ou "Error". Pour autant que je sache, les modules intégrés (built-in) utilisent "error" (par exemple os.error), tandis que les modules Python utilisent généralement "Error" (par exemple xdrlib.Error).

Les Noms de Fonctions

Les fonctions simples exportées par un module peuvent utiliser aussi bien le style MotCapitalisé ou minuscule (ou encore : minuscule_avec_soulignes). Je n'ai pas de grosse préférence, mais je crois que le style MotCapitalisé est utilisé pour des fonctions qui procurent des fonctionnalités majeures (par exemple nstools.WorldOpen()), tandis que les minuscules sont utilisées pour des fonctions plus "utilitaires" (par exemple pathhack.kos_root()).

Les Noms de variables Globales

(En espérant que ces variables sont destinées à n'être utilisée qu'à l'intérieur d'un module.) Les conventions sont à peu près les mêmes que celles pour les fonctions exportées. Les modules qui sont prévus pour être utilisés via "from M import *" devraient préfixer leurs variables globales (et leurs fonctions et classes internes) avec un souligné, pour empêcher leur exportation.

Les Noms de Méthodes

Hmm, l'histoire est largement la même que pour les fonctions. Quand on utilise ILU, voici une bonne convention: utilisez les MotsCapitalisés pour les méthodes publiées via une interface ILU. Utilisez les minuscules pour les méthodes accédées par d'autres classes ou fonctions qui font partie de l'implémentation d'un type d'objets. Utilisez une souligné en tête pour les méthodes et variables d'instances internes quand il n'y a aucun risque de conflit avec les attributs de sous-classes ou de superclasses, ou dans le cas où une sous-classe risque d'avoir besoin d'y accéder. Utilisez deux soulignés en tête (noms de classes privés, imposés par Python 1.4) dans ces mêmes cas, quand il est important que seule la classe courante accède à un attribut. (mais n'oubliez pas que Python contient assez d'échappatoires pour qu'un utilisateur têtu puisse néanmoins obtenir un accès, par exemple au moyen de l'attribut __dict__. Seul ILU ou le mode protégé de Python XXXX