PEP 8 – Style Guide for Python Code
Introduction
Ce document donne des conventions de "codage" en Python.
Ce document n'est qu'un extrait du document officiel complet et en Anglais.
Présentation du code
Indentation
Utiliser 4 espaces par niveau d'indentation.
# Correct:
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)
# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
# Hanging indents should add a level.
foo = long_function_name(
var_one, var_two,
var_three, var_four)
# Wrong:
# Arguments on first line forbidden when not using vertical alignment.
foo = long_function_name(var_one, var_two,
var_three, var_four)
# Further indentation required as indentation is not distinguishable.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
La règle des 4 espaces est optionnelle si l'instruction s'étend sur plusieurs lignes.
Optionnel:
# Hanging indents *may* be indented to other than 4 spaces.
foo = long_function_name(
var_one, var_two,
var_three, var_four)
La parenthèse/accolade/crochet fermante des constructions sur plusieurs lignes peut au choix s'aligner sur le 1er caractère (non blanc) de la dernière ligne, comme dans :
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
ou bien s'aligner sous le 1er caractère de la ligne qui a commencé l'instruction multiligne, comme dans :
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
Tabulations ou espaces ?
Les espaces sont préférés.
Les tabulations ne doivent être utilisées que si l'ensemble du code les utilise.
En aucun cas, on ne mélange tabulations et espaces.
Imports
- Les imports devraient être sur des lignes séparés :
# Correct: import os import sys
# Wrong: import sys, os
Cependant, on tolère ceci :
# Correct: from subprocess import Popen, PIPE
- Les imports se font au début du code.
Ils doivent être groupés selon l'ordre suivant :
- Import de la Standard library.
- Imports des Related third party.
- Imports des Local application/library specific.
- Les imports avec "Wildcard" [le caractère *] (
from <module> import *
) devraient être évités, car cela risque de perturber l'espace de nommage.
Guillemets (quotes) des chaînes de caractères
En Python, les simples ou doubles guillemets sont équivalents pour les chaînes de caractères. Cette PEP n'émet aucune recommandation à ce sujet. Choisissez une règle, et n'en changez pas.
Pour les chaînes à triples guillemets (ex : docstring), utilisez toujours les guillemets doubles.
Espaces dans les expressions et déclarations
Manies agaçantes
Évitez les espaces supplémentaires dans les situations suivantes :
- Immédiatement entre parenthèses, accolades ou crochets :
# Correct: spam(ham[1], {eggs: 2})
# Wrong: spam( ham[ 1 ], { eggs: 2 } )
- Entre une virgule terminale et une parenthèse fermante:
# Correct: foo = (0,)
# Wrong: bar = (0, )
- Immédiatement avant une virgule, un point-virgule ou deux-points :
# Correct: if x == 4: print(x, y); x, y = y, x
# Wrong: if x == 4 : print(x , y) ; x , y = y , x
- Cependant, dans une tranche (slice) les deux-points se comportent comme un opérateur
binaire, et devraient avoir le même espacement avant et après. Exception :
quand un paramètre de tranche est omis, l'espace est omis :
# Correct: ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:] ham[lower:upper], ham[lower:upper:], ham[lower::step] ham[lower+offset : upper+offset] ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] ham[lower + offset : upper + offset]
# Wrong: ham[lower + offset:upper + offset] ham[1: 9], ham[1 :9], ham[1:9 :3] ham[lower : : step] ham[ : upper]
- Immédiatement avant la parenthèse ouvrante d'une liste d'arguments d'un appel de
fonction :
# Correct: spam(1)
# Wrong: spam (1)
- Immédiatement avant la parenthèse ouvrante d'un indice ou d'une tranche :
# Correct: dct['key'] = lst[index]
# Wrong: dct ['key'] = lst [index]
- Plus d'un espace autour de l'opérateur d'affectation pour s'aligner avec un autre :
# Correct: x = 1 y = 2 long_variable = 3
# Wrong: x = 1 y = 2 long_variable = 3
Autres recommandations
- Évitez partout les espaces trainant (en fin de ligne).
- Entourez toujours ces opérateurs binaires d'un espace : affectation (
=
), incrémentation (+=
,-=
etc.), comparaisons (==
,<
,>
,!=
,<>
,<=
,>=
,in
,not in
,is
,is not
), booléens (and
,or
,not
). - Si des opérateurs avec differentes prioritiés sont utilisés, on peut ajouter un espace
autour des opérateurs avec la(les) plus basse(s) priorité(s). Faites selon votre
jugement ; cependant, n'utilisez jamais plus d'un espace, avec toujours le même espace
autour d'un opérateur binaire :
# Correct: i = i + 1 submitted += 1 x = x*2 - 1 hypot2 = x*x + y*y c = (a+b) * (a-b)
# Wrong: i=i+1 submitted +=1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b)
- Pas d'espace autour du signe égal
=
quand il est utilisé pour désigner un argument de fonction :# Correct: def complex(real, imag=0.0): return magic(r=real, i=imag)
# Wrong: def complex(real, imag = 0.0): return magic(r = real, i = imag)
Conventions de nommage
Principe primordial
Les noms choisis doivent traduire l'usage plutôt que l'implémentation.
Descriptive: Naming Styles
Il y a de nombreux styles de nommage. Il est pratique de reconnaître ces styles, indépendamment de ce pour quoi ils sont utilisés.
Les styles de nommage suivants sont couramment distingués :
b
(single lowercase letter)B
(single uppercase letter)lowercase
lower_case_with_underscores
UPPERCASE
UPPER_CASE_WITH_UNDERSCORES
CapitalizedWords
(ou CamelCase – ainsi nommmé à cause de l'allure bosselée de ses lettres).mixedCase
(diffère du CapitalizedWords par la minuscule de la 1ère lettre)Capitalized_Words_With_Underscores
(affreux !)
Par ailleurs, l'usage d'underscore (simple ou double) en début ou fin de nom correspondent à des usages particuliers (comme par exemple) :
single_trailing_underscore_
: utilisés pour éviter les conflts de noms avec les mots-clefs de Python, ex. :tkinter.Toplevel(master, class_='ClassName')
__double_leading_and_trailing_underscore__
: objets “magiques” ou attributs cachés. Ex.__init__
,__import__
ou__file__
.
Prescriptions sur les conventions de nommage
Noms à éviter
Ne jamais utiliséer seul le caractère ‘l’ (lowercase letter el), ou ‘O’ (uppercase letter oh), ou ‘I’ (uppercase letter eye) comme nom de variable. Avec certaines polices, ces caractères sont confondus avec les chiffres 1 ou 0.
Compatibilité ASCII
Les identifiants choisis doivent être compatibles avec l'encodage ASCII.
Noms de Classes
Les noms de classes doivent suivre la convention CapWords.
Noms des fonctions et variables
Les noms de fonctions sont en minuscules, avec les mmots séparés par des underscore.
Les noms de variables suivent ces mêmes conventions.
Paramètres des fonctions et méthodes
Toujours utiliser self
pour le
1er paramètre des méthodes d'instance.
Toujours utiliser cls
pour le 1er paramètre des méthodes de classe.
Constantes
Les constantes sont générallement écrites en lettres capitales avec des underscore entre les mots. Ex :
MAX_OVERFLOW
ou TOTAL
.
Recommandations de programmation
- Les comparaisons à des singletons comme None doivent être faites avec
is
ouis not
, jamais avec l'opérateur d'égalité. - Utilisez
is not
plutôt quenot ... is
. Bien que les deux soient fonctionnellement identiques, la 1ère façon est plus lisible et préférée :# Correct: if foo is not None:
# Wrong: if not foo is None:
- Soyez consistants dans les déclarations return. Soit toutes les déclarations return renvoient une expression, ou alors aucune. Si une déclaration return renvoie une expression, alors toute déclaration return où aucune valeur n'est renvoyée doit explicitement indiquer
return None
, et une déclaration return explicite doit être présente à la fin de la fonction :# Correct: def foo(x): if x >= 0: return math.sqrt(x) else: return None def bar(x): if x < 0: return None return math.sqrt(x)
# Wrong: def foo(x): if x >= 0: return math.sqrt(x) def bar(x): if x < 0: return return math.sqrt(x)
- Utilisez
''.startswith()
et''.endswith()
au lieu d'un "slicing" pour contôler un préfixe ou un suffixe.startswith() et endswith() sont plus propres et moins sujets aux erreurs :
# Correct: if foo.startswith('bar'):
# Wrong: if foo[:3] == 'bar':
- Les comparaisons de type d'un objet doivent être faites avec la fonction isinstance() au lieu de comparer les types directement :
# Correct: if isinstance(obj, int):
# Wrong: if type(obj) is type(1):
- Ne comparez les valeurs booléenes à True ou False en utilisant
==
:# Correct: if greeting:
# Wrong: if greeting == True:
Pire:
# Wrong: if greeting is True:
Commentaires
Les commentaires qui contredisent le code sont pires qu'aucun commentaire. Faites une priorité de mettre à jour les commentaires lorsuqe le code change !
Les comments doivent être des phrases compètes. Le 1er mmot commence par une majuscule (sauf si c'est un identifiant).
Les commentaires en bloc sont un ou plusieurs paragraphes construits avec des phrases complètes, terminant par un point.
Progammeurs Python de pays non anglophones : svp écrivez vos commentaires en Anglais, à moins que vous soyez certains à 120% que le code ne sera pas lu par quelqu'un qui ne parle pas votre langue.
Commentaires en bloc
Les commentaires en bloc s'appliquent en général à tout ou partie du code qui les suit, et sont indentés comme ce code. Chaque ligne du bloc commence avec
#
et un simple espace.Les paragraphes du bloc sont séparés par une ligne conentant uniquement
#
.Commentaires en ligne
Utilisez les commentaires en ligne avec parcimonie.
Un commentaire en ligne est sur la même ligne qu'une déclaration. Les commentaires en ligne doivent être séparés par au moins deux espaces de la déclaration. Ils commencent avec # et un simple espace.
Les commentaires en ligne sont inutiles et perturbants s'ils déclarent des évidences. Ne faites pas ceci :
Mais parfois, c'est utile :
Chaînes de Documentation (docstring)
Les conventions pour écrire de bonnes docstring sont décrites dans la PEP 257.
def
."""
qui terminent une docstring multiligne doivent être sur une ligne séparée :"""
fermants sur la même ligne :"""Return an ex-parrot."""