L'interprétation de Python des onglets et des espaces à indenter

j'ai décidé que j'apprenais un peu de Python. La première introduction dit qu'il utilise l'indentation pour grouper des déclarations. Alors que la meilleure habitude est clairement d'utiliser un seul de ces ce qui se passe si je les échange? Combien d'espaces seront considérés comme égaux à un onglet? Ou ne pas fonctionner du tout si les tabulations et des espaces sont mélangés?

27
demandé sur Lukas 2010-01-09 21:57:25

7 réponses

Les espaces

ne sont pas traités comme équivalents à tab. Une ligne indentée avec un onglet est à une indentation différente d'une ligne indentée avec 1, 2, 4 ou 8 espaces.

preuve par contre-exemple ( erroné, ou, au mieux, limité-tab != 4 espaces ):

x = 1
if x == 1:
^Iprint "fff\n"
    print "yyy\n"

le" ^I "montre un TAB . Quand Python 2.5 est exécuté, j'obtiens l'erreur:

  File "xx.py", line 4
    print "yyy\n"
                ^
IndentationError: unindent does not match any outer indentation level

montrant ainsi que dans Python 2.5, les onglets ne sont pas égaux à des espaces (et en particulier pas égaux à 4 espaces).


Oups - embarrassante; ma preuve par le contre-exemple montre que les onglets ne sont pas l'équivalent de 4 espaces. Comme Alex Martelli le souligne dans un commentaire , en Python 2, les onglets sont équivalents à 8 espaces, et l'adaptation de l'exemple avec un onglet et 8 espaces montre que c'est bien le cas.

x = 1
if x != 1:
^Iprint "x is not 1\n"
        print "y is unset\n"

en Python 2, ce code fonctionne, n'imprimant rien.


en Python 3, les règles sont légèrement différentes (comme noté par Antti Haapala ). Comparer:

Python 2 dit:

tout d'abord, les onglets sont remplacés (de gauche à droite) par un à huit espaces de telle sorte que le nombre total de caractères allant jusqu'à et incluant le remplacement est un multiple de huit (ceci est censé être la même règle que celle utilisée par Unix). Le nombre total d'espaces précédant le premier caractère non vide détermine alors l'indentation de la ligne. L'Indentation ne peut pas être divisée sur plusieurs lignes physiques à l'aide d'antislashs; les espaces vers le haut à la première barre oblique inverse détermine l'indentation.

Python 3 dit:

Les onglets

sont remplacés (de gauche à droite) par un ou huit espaces de telle sorte que le nombre total de caractères pouvant aller jusqu'au remplacement est un multiple de huit (ce qui est censé être la même règle que celle utilisée par Unix). Le nombre total d'espaces précédant le premier caractère non vide détermine alors l'indentation de la ligne. L'Indentation ne peut être répartie sur plusieurs lignes physiques à l'aide de barres obliques inverses; les espaces jusqu'à la première barre oblique inverse détermine l'indentation.

(outre le mot d'ouverture" Premier", ceux-ci sont identiques.)

Python 3 ajoute un paragraphe supplémentaire:

Indentation est rejetée comme incohérente si un fichier source mélange des onglets et des espaces d'une manière qui rend le sens dépendant de la valeur d'un onglet dans les espaces; un TabError est élevé dans ce cas.

cela signifie que le onglet vs 8-Exemple d'espace qui a fonctionné en Python 2 générerait un TabError en Python 3. Il est préférable - nécessaire dans Python 3-de s'assurer que la séquence des caractères constituant l'indentation sur chaque ligne d'un bloc est identique. PEP8 dit "Utilisez 4 espaces par niveau d'indentation". (Les normes de codage de Google disent "utiliser 2 espaces".)

33
répondu Jonathan Leffler 2017-02-24 19:41:48

Suivre PEP 8 pour Python style. PEP 8 dit: Indentation

Utilisez 4 espaces par niveau d'indentation.

vraiment ancien code que vous ne voulez pas gâcher, vous pouvez continuer pour utiliser des onglets de 8 espaces.

onglets ou espaces?

ne mélange jamais les onglets et les espaces.

la manière la plus populaire d'indenter Python est avec des espaces seulement. Le deuxième plus populaire est, avec des onglets. Code indenté avec une le mélange d'onglets et d'espaces doit être converti en utilisant des espaces exclusivement. En invoquant l'interpréteur En Ligne de commande Python avec l'option-t, elle émet des avertissements sur le code qui mélange illégalement des onglets et des espaces. En utilisant l'option-tt, ces avertissements deviennent des erreurs. Ils les options sont fortement recommandés!

18
répondu Eli Bendersky 2015-08-14 09:21:47

dans Python 2, l'interprétation de TAB est comme si elle était convertie en espaces en utilisant 8-espace tab stop (tel que fourni par les réponses précédentes déjà); c'est-à-dire que chaque TAB rallonge l'indentation de 1 à 8 espaces de sorte que l'indentation résultante est divisible par 8.

cependant cela ne s'applique plus à Python 3 désormais - dans le mélange de Python 3 des espaces et des onglets sont toujours une erreur - onglets seulement les onglets de correspondance et les espaces ne correspondent qu'à d'autres espaces dans l'indentation; c'est-à-dire une ligne indentée avec onglet espace "espace peut contenir aussi des lignes indentées avec espace " espace " TAB ; et pourrait contenir un bloc indenté indenté avec TAB espace espace TAB , mais si elle bloc en retrait contenant onglet onglet , il serait considéré comme un erreur d'indentation, même si le blocage semble s'étendre davantage:

Indentation est rejetée comme incohérente si un fichier source mélange des onglets et des espaces d'une manière qui rend le sens dépendant de la valeur d'un onglet dans les espaces; un TabError est soulevé dans ce cas.

I. e. l'algorithme fonctionne comme suit:

  • si les deux nombres d'onglets et nombre d'espaces correspond à la ligne précédente (peu importe l'ordre), alors cette ligne appartient au même bloc avec la ligne précédente

  • si le nombre de l'un des (onglets, espaces) est supérieur à celui de la ligne précédente et que le nombre de l'autre est au moins égal à celui de la ligne précédente, il s'agit d'un bloc en retrait

    1519490920"
  • le tuple (tabs, spaces) correspond à un tiret d'un bloc précédent - ce dedents à ce bloc

  • sinon un IndentationError ou un TabError est soulevé.

c'est pourquoi mélanger des onglets et des espaces, ou même utiliser des onglets pour indentation serait considéré comme une très mauvaise pratique en Python.

8
répondu Antti Haapala 2017-02-24 19:32:30

il suffit de ne pas les échanger:)

Réglez votre IDE / editor à l'entrée de 4 espaces en appuyant sur " tab " et vous êtes bon pour aller.

5
répondu shylent 2010-01-09 19:01:18

je vous recommande de passer par PEP 8 qui est le guide de style Python "officiel" pour le code Python. Il couvre (entre autres choses) l'utilisation d'onglets/espaces.

5
répondu Noufal Ibrahim 2018-07-03 02:58:41

Quatre espaces sont un onglet (dans ma configuration), mais autant que je sache, ils ne sont pas interchangeables. Vous pouvez utiliser des espaces ou des tabulations, pas les deux.

2
répondu Amirshk 2018-07-03 02:58:17

je crois que le caractère de l'onglet ne devrait tout simplement jamais apparaître dans le code source dans toutes les circonstances. Il n'y a aucun avantage à cela et c'est une source sans fin de petites erreurs. - utiliser une chaîne de caractères \t si vous avez besoin d'un onglet, il a l'avantage, c'est l'auto-documentation.

ici l ' article classique sur les onglets vs espaces - j'utilise une variante de JWZ elisp dans mon propre .fichier emacs.

(j'avoue, personnellement casser avec PEP 8 en utilisant seulement 2 caractères d'indentation-4 caractères est beaucoup quand vos lignes sont seulement 80 caractères...)

0
répondu Tom Swirly 2010-01-09 23:04:40