Pourquoi l'indentation est-elle importante ?
En Python, l'indentation est utilisée pour délimiter les éléments suivants blocs de code . C'est différent de nombreux autres langages qui utilisent les accolades. {}
pour délimiter des blocs tels que Java, Javascript et C. Pour cette raison, les utilisateurs de Python doivent faire très attention à quand et comment ils indentent leur code, car l'espace blanc est important.
Lorsque Python rencontre un problème avec l'indentation de votre programme, il lève une exception appelée IndentationError
o TabError
.
Un peu d'histoire
Les raisons historiques pour lesquelles Python utilise l'indentation plutôt que les accolades, sans doute plus courantes. {}
est décrit dans un article sur l'histoire de Python par Guido van Rossum - le créateur de Python :
L'utilisation de l'indentation dans Python provient directement d'ABC, mais cette idée n'est pas née avec ABC - elle avait déjà été promue par Donald Knuth et était un concept bien connu du style de programmation. (Le langage de programmation occam l'utilisait également.) Cependant, les auteurs d'ABC ont inventé l'utilisation des deux points qui séparent la clause d'introduction du bloc indenté. Après les premiers tests effectués par les utilisateurs sans les deux-points, il s'est avéré que la signification de l'indentation n'était pas claire pour les débutants qui apprenaient les premières étapes de la programmation. L'ajout des deux-points a permis de clarifier la situation de manière significative : les deux-points attirent en quelque sorte l'attention sur ce qui suit et relient les phrases qui les précèdent et les suivent de la bonne manière.
Comment indenter mon code ?
La règle de base pour l'indentation du code Python (en considérant que vous traitez l'ensemble du programme comme un "bloc de base") est la suivante : La première instruction d'un bloc de base, et chaque instruction suivante, doivent être indentées de la même manière.
Donc techniquement, le programme Python suivant est correct :
def perm(l):
# Compute the list of all permutations of l
if len(l) <= 1:
return [l]
r = []
for i in range(len(l)):
s = l[:i] + l[i+1:]
p = perm(s)
for x in p:
r.append(l[i:i+1] + x)
return r
Cependant, comme vous pouvez le constater, l'indentation aléatoire de votre code rend la lecture et le suivi du programme extrêmement difficiles. Il est préférable d'être cohérent et de suivre un style.
PEP 8 -- le guide de style de Python -- indique que :
Utilisez 4 espaces par niveau d'indentation.
C'est-à-dire, chaque déclaration qui commence un nouveau bloc et chaque déclaration suivante dans le nouveau bloc, doit être indentée de quatre espaces à partir du niveau d'indentation actuel. . Voici le programme ci-dessus mis en retrait selon le guide de style PEP8 :
def perm(l):
# Compute the list of all permutations of l
if len(l) <= 1:
return [l]
r = []
for i in range(len(l)):
s = l[:i] + l[i+1:]
p = perm(s)
for x in p:
r.append(l[i:i+1] + x)
return r
Puis-je encore utiliser des onglets ?
Python est conscient que certaines personnes préfèrent encore les tabulations aux espaces et que les codes hérités peuvent utiliser les tabulations plutôt que les espaces, il autorise donc l'utilisation des tabulations comme indentation. Le PEP8 aborde ce sujet :
Les espaces sont la méthode d'indentation préférée.
Les tabulations doivent être utilisées uniquement pour rester cohérent avec le code qui est déjà indenté avec des tabulations.
Notez cependant qu'il y a un gros problème. de ne pas utiliser les deux onglets et espaces pour l'indentation . Cela peut provoquer toutes sortes d'erreurs d'indentation étranges et difficiles à déboguer. Python étend les tabulations jusqu'à la huitième colonne suivante, mais si votre éditeur est réglé sur une taille de tabulation de 4 colonnes, ou si vous utilisez des espaces en plus des tabulations, vous pouvez facilement produire du code indenté qui regarde dans votre éditeur, mais Python refusera de s'exécuter. Le compilateur Python 3 explicitement rejette tout programme contenant un mélange ambigu de tabulations et d'espaces, généralement en émettant un message d'erreur. TabError
. Cependant, par défaut, le mélange des tabulations et des espaces est toujours autorisé dans Python 2, mais il est fortement recommandé de ne pas utiliser cette "fonctionnalité". Utilisez l'option -t
y -tt
pour forcer Python 2 à afficher respectivement un avertissement ou (de préférence) une erreur. Le PEP8 aborde également ce sujet :
Python 3 ne permet pas de mélanger l'utilisation des tabulations et des espaces pour l'indentation.
Le code Python 2 indenté avec un mélange de tabulations et d'espaces doit être converti en utilisant exclusivement des espaces.
Lorsque l'interpréteur de ligne de commande Python 2 est invoqué avec l'option -t, il émet des avertissements concernant le code qui mélange illégalement les tabulations et les espaces. En utilisant l'option -tt, ces avertissements deviennent des erreurs. Ces options sont fortement recommandées !
Que signifie "IndentationError : unexpected indent" ?
Problème
Cette erreur se produit lorsqu'une instruction est indentée inutilement ou que son indentation ne correspond pas à celle des instructions précédentes dans le même bloc. Par exemple, la première instruction du programme ci-dessous est indentée inutilement :
>>> print('Hello') # this is indented
File "<stdin>", line 1
print('Hello') # this is indented
^
IndentationError: unexpected indent
Dans cet exemple, le can_drive = True
dans le if
ne correspond pas à l'indentation d'une déclaration antérieure :
>>> age = 10
>>> can_drive = None
>>>
>>> if age >= 18:
... print('You can drive')
... can_drive = True # incorrectly indented
File "<stdin>", line 3
can_drive = True # incorrectly indented
^
IndentationError: unexpected indent
Fixer
Pour corriger cette erreur, il faut d'abord s'assurer que la ligne problématique doit être indentée. Par exemple, l'exemple ci-dessus utilisant print
peut être corrigé simplement en désindentant la ligne :
>>> print('Hello') # simply unindent the line
Hello
Toutefois, si vous êtes sûr que la ligne doit être indentée, l'indentation doit correspondre à celle d'une déclaration antérieure dans le même bloc. Dans le deuxième exemple ci-dessus utilisant if
on peut corriger l'erreur en s'assurant que la ligne avec can_drive = True
est indentée au même niveau que les déclarations antérieures dans la section if
corps :
>>> age = 10
>>> can_drive = None
>>>
>>> if age >= 18:
... print('You can drive')
... can_drive = True # indent this line at the same level.
...
Que signifie "IndentationError : expected an indented block" ?
(Cela peut aussi se produire comme SyntaxError: unexpected EOF while parsing
en Python 3.8 ou inférieur).
Problème
Cette erreur se produit lorsque Python voit l'"en-tête" d'une instruction composée, telle que if <condition>:
o while <condition>:
mais le corps de l'instruction composée ou bloc n'est jamais défini. Par exemple, dans le code ci-dessous, nous avons commencé un if
mais nous ne définissons jamais de corps pour cette déclaration :
>>> if True:
...
File "<stdin>", line 2
^
IndentationError: expected an indented block
Dans ce deuxième exemple, nous avons commencé à écrire un for
mais nous avons oublié d'indenter les for
corps de la boucle. Ainsi, Python s'attend toujours à un bloc indenté pour la boucle for
corps de la boucle :
>>> names = ['sarah', 'lucy', 'michael']
>>> for name in names:
... print(name)
File "<stdin>", line 2
print(name)
^
IndentationError: expected an indented block
Les commentaires ne comptent pas comme des corps :
>>> if True:
... # TODO
...
File "<stdin>", line 3
^
IndentationError: expected an indented block
Fixer
Pour corriger cette erreur, il suffit d'inclure un corps pour l'instruction composée.
Comme nous l'avons vu plus haut, une erreur fréquente des nouveaux utilisateurs est d'oublier d'indenter le corps du texte. Si c'est le cas, assurez-vous que chaque instruction destinée à être incluse dans le corps de l'instruction composée est indentée au même niveau sous le début de l'instruction composée. Voici l'exemple ci-dessus corrigé :
>>> names = ['sarah', 'lucy', 'michael']
>>> for name in names:
... print(name) # The for loop body is now correctly indented.
...
sarah
lucy
michael
Un autre cas fréquent est que, pour une raison ou une autre, l'utilisateur ne souhaite pas définir un corps réel pour l'instruction composée, ou le corps peut être commenté. Dans ce cas, la fonction pass
peut être utilisée. Le site pass
peut être utilisée partout où Python attend une ou plusieurs déclarations en tant que placeholder. Dans la documentation de pass
:
pass est une opération nulle - lorsqu'elle est exécutée, rien ne se passe. Elle est utile en tant que paramètre de remplacement lorsqu'une déclaration est requise sur le plan syntaxique, mais qu'aucun code ne doit être exécuté, par exemple :
def f(arg): pass # a function that does nothing (yet)
class C: pass # a class with no methods (yet)
Voici l'exemple ci-dessus avec le if
fixé par l'utilisation de la pass
mot-clé :
>>> if True:
... pass # We don't want to define a body.
...
>>>
Que signifie "IndentationError : unindent does not match any outer indentation level" ?
Problème
Cette erreur se produit lorsque vous désindentez une instruction, mais que le niveau d'indentation de cette instruction ne correspond pas à celui d'une instruction précédente. Par exemple, dans le code ci-dessous, nous désindentons le deuxième appel à print
. Cependant, le niveau d'indentation ne correspond pas à celui d'une déclaration antérieure :
>>> if True:
... if True:
... print('yes')
... print()
File "<stdin>", line 4
print()
^
IndentationError: unindent does not match any outer indentation level
Cette erreur est particulièrement difficile à détecter, car un seul espace entraîne l'échec de votre code.
Fixer
La solution consiste à s'assurer que lorsque vous désindentez une déclaration, le niveau d'indentation correspond à celui de la déclaration précédente. Reprenons l'exemple ci-dessus. Dans l'exemple, je veux que le deuxième appel à print se trouve dans la première instruction if
corps de déclarations. Je dois donc veiller à ce que le niveau d'indentation de cette ligne corresponde à celui des déclarations précédentes dans la première section de l'article. if
le corps de la déclaration :
>>> if True:
... if True:
... print('yes')
... print() # indentation level now matches former statement's level.
...
yes
>>>
Je reçois toujours un IndentationError mais mon programme semble être correctement indenté. Que dois-je faire ?
Si votre programme semble visuellement avoir une indentation correcte, mais que vous obtenez toujours le message IndentationError
vous avez très probablement mélange de tabulations et d'espaces . Cela peut parfois provoquer des erreurs étranges dans Python. Voir la sous-section Cas particuliers sous Que signifie "TabError : inconsistent use of tabs and spaces in indentation" ? pour une explication plus approfondie du problème.
Que signifie "TabError : inconsistent use of tabs and spaces in indentation" ?
Problème
Cette erreur ne se produit que lorsque vous tentez de mélanger les tabulations et les espaces comme caractères d'indentation. Comme indiqué ci-dessus, Python ne permettra pas à votre programme de contenir un mélange de tabulations et d'espaces, et soulèvera l'exception spécifique suivante TabError
s'il découvre que vous l'avez fait. Par exemple, dans le programme ci-dessous, un mélange de tabulations et d'espaces est utilisé pour l'indentation :
>>> if True:
... if True:
... print()
... print()
... print()
File "<stdin>", line 5
print()
^
TabError: inconsistent use of tabs and spaces in indentation
Voici une image qui montre visuellement les espaces blancs dans le programme ci-dessus. Les points gris sont des espaces, et les flèches grises sont des tabulations :
Nous pouvons voir que nous avons effectivement mélangé espaces et tabulations pour l'indentation.
Cas particuliers
Note Python ne sera pas toujours soulever un TabError
si vous mélangez les tabulations et les espaces dans votre programme. Si l'indentation du programme est sans ambiguïté, Python autorisera le mélange de tabulations et d'espaces. Par exemple :
>>> if True:
... if True: # tab
... pass # tab, then 4 spaces
...
>>>
Et parfois, Python s'étrangle tout simplement avec le mélange de tabulations et d'espaces et génère par erreur un message d'erreur IndentationError
exception lorsqu'un TabError
serait plus approprié. Un autre exemple :
>>> if True:
... pass # tab
... pass # 4 spaces
File "<stdin>", line 3
pass # 4 spaces
^
IndentationError: unindent does not match any outer indentation level
Comme vous pouvez le constater, exécuter votre code de cette manière peut créer des erreurs mystérieuses. Même si le programme visuellement semble bien fonctionner, Python s'est embrouillé en essayant d'analyser les tabulations et les espaces utilisés pour les indentations et s'est trompé.
Ces excellents exemples démontrent qu'il ne faut jamais mélanger les tabulations et les espaces et qu'il faut utiliser la touche -t
y -tt
les drapeaux de l'interpréteur lorsque vous utilisez Python 2.
Fixer
Si votre programme est court, la solution la plus simple et la plus rapide consiste à le réindenter. Assurez-vous que chaque instruction est indentée de quatre espaces par niveau d'indentation (cf. Comment indenter mon code ? ).
Cependant, si vous avez déjà un gros programme dans lequel vous avez mélangé des tabulations et des espaces, il existe des outils automatisés qui peuvent être utilisés pour convertir toute votre indentation en espaces seulement.
De nombreux éditeurs, tels que PyCharm y SublimeText disposent d'options permettant de convertir automatiquement les tabulations en espaces. Il existe également plusieurs outils en ligne tels que Des onglets aux espaces o Browserling qui vous permettent de réindenter rapidement votre code. Il existe également des outils écrits en Python. autopep8 par exemple, peut automatiquement réindenter votre code et corriger également d'autres erreurs d'indentation.
Cependant, même les meilleurs outils ne seront parfois pas en mesure de corriger toutes vos erreurs d'indentation et vous devrez les corriger manuellement. C'est pourquoi il est important de toujours indenter correctement votre code dès le départ.
Une note sur les problèmes d'indentation liés aux "SyntaxError".
Bien que cela ne soit pas fréquent, il arrive que certaines SyntaxError
des exceptions sont soulevées en raison d'une indentation incorrecte. Par exemple, regardez le code ci-dessous :
if True:
pass
pass # oops! this statement should be indented!.
else:
pass
Lorsque le code ci-dessus est exécuté, un SyntaxError
est soulevée :
Traceback (most recent call last):
File "python", line 4
else:
^
SyntaxError: invalid syntax
Bien que Python soulève un SyntaxError
le réel Le problème avec le code ci-dessus est que le deuxième pass
doit être mis en retrait. Parce que la deuxième pass
n'est pas indenté, Python ne se rend pas compte que le précédent if
et la else
Les déclarations sont destinées à être connectées.
La solution pour ce type d'erreur consiste simplement à réindenter correctement votre code. Pour savoir comment indenter correctement votre code, consultez la section Comment indenter mon code ? .
J'ai toujours du mal avec la syntaxe d'indentation de Python. Que dois-je faire ?
Ne vous découragez pas si vous avez encore des difficultés. Il faut parfois du temps pour s'habituer à règles de syntaxe des espaces blancs de Python. Voici quelques conseils pour vous aider :
- Procurez-vous un éditeur qui vous signale les erreurs d'indentation. Certains biens sont comme dit ci-dessus, PyCharm , SublimeText y Jupyter Notebook .
- Lorsque vous indentez votre code, comptez à haute voix le nombre de fois où vous appuyez sur la barre d'espacement (ou la touche de tabulation). Par exemple, si vous devez indenter une ligne de quatre espaces, vous direz à haute voix " un , deux , trois , quatre "tout en appuyant simultanément sur la barre d'espacement à chaque fois. Cela peut paraître idiot, mais cela aide à entraîner votre cerveau à réfléchir à la profondeur de l'indentation de votre code.
- Si vous avez un éditeur, voyez s'il dispose d'une option permettant de convertir automatiquement les tabulations en espaces.
- Voir le code des autres. Parcourir github o Stackoverflow et voir des exemples de code Python.
- Il suffit d'écrire le code. C'est le meilleur moyen de s'améliorer. Plus vous écrirez du code Python, plus vous vous améliorerez.
Ressources utilisées
1 votes
Si quelqu'un soulève un problème à ce sujet... posez simplement une question à ce sujet sur Meta Stack Overflow. C'est le meilleur lieu pour gérer la discussion sur l'opportunité ou non de cette question, et même si elle serait appropriée comme cible de dupe du tout.
10 votes
Une autre perspective : Je ne considère pas la plupart des problèmes d'indentation comme des fautes de frappe, donc je vais continuer à les fermer en double, et je pourrais utiliser ceci comme cible de double.