Python对制表符和空格的解释来缩进。

40
我决定学一点Python。第一次介绍说它使用缩进来分组语句。虽然最好的习惯显然是只使用其中一种,但如果我交换它们会发生什么?多少个空格被认为等于一个制表符?或者如果混合使用制表符和空格,它会完全无法工作吗?
请使用我遇到了IndentationError(或TabError)。我该如何修复它?来关闭那些由于混合使用制表符和空格而导致缩进错误的问题。这个问题特别讨论了这种缩进是如何解释的,而不是为什么会导致问题或如何修复它。
7个回答

44

空格不能等同于制表符。使用制表符缩进的行与使用1、2、4个空格缩进的行处于不同的缩进级别,或者8个空格

反例证明(错误的,或者最好只是有限的 - 制表符不等于4个空格):

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

"

'^I'代表一个TAB。当在Python 2.5中运行时,我会收到错误信息:

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

因此,这表明在Python 2.5中,制表符不等于空格(特别是不等于4个空格)。

糟糕 - 尴尬了;我的反例证明表明制表符不等同于4个空格。正如Alex Martelli评论中指出的那样,在Python 2中,制表符相当于8个空格,并且使用制表符和8个空格来调整示例可以证明这确实是情况。

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

在Python 2中,这段代码可以正常运行,但不会打印任何内容。
在Python 3中,规则略有不同(如noted所述,由Antti Haapala)。比较如下: Python 2表示:

首先,制表符将被替换为一个到八个空格,使得包括替换在内的总字符数是8的倍数(这意味着与Unix使用的相同规则)。然后,第一个非空白字符之前的空格确定了行的缩进。不能使用反斜杠在多个物理行上分割缩进;第一个反斜杠之前的空格决定了缩进。

Python 3表示:
制表符(Tab)将从左到右被替换为一个到八个空格,使得包括替换在内的字符总数是8的倍数(这是Unix使用的相同规则)。然后,第一个非空白字符之前的空格确定了行的缩进。无法使用反斜杠将缩进分成多个物理行;第一个反斜杠之前的空格确定缩进。Python 3增加了一个额外的段落:如果源文件混合使用制表符和空格,以一种使得含义依赖于制表符在空格中的价值的方式,则缩进将被拒绝为不一致;在这种情况下会引发TabError错误。
这意味着在Python 2中有效的TAB与8个空格的示例在Python 3中会生成TabError。在Python 3中,最好确保每个块中每行缩进的字符序列是相同的,这是必要的。PEP8建议“每个缩进级别使用4个空格”(Google的编码标准建议“使用2个空格”)。

@JonathanLeffler 是的,从“它跟随一个段落”开始的补充说明特别指出制表符的大小并不重要,一个制表符只匹配缩进中的一个制表符;一个空格只匹配缩进中的一个空格。 - Antti Haapala -- Слава Україні
只是,这些行在回溯中缩进了8个空格。 - Antti Haapala -- Слава Україні
Python3中答案中引用的“额外段落”听起来很好,但实际上似乎并不是那样。可以在http://pastebin.com/q6F8Fj0h看到一个反例(但您必须在每个LF之前删除CR)。它会在制表位为1时以一种方式缩进,在制表位为2时以另一种方式缩进。但是Python 3.6和Python 3.7不会拒绝它;它可以正常运行。 - Bill Evans at Mariposa

22

遵循PEP 8的Python风格指南。PEP 8指出:

每个缩进级别使用4个空格。

对于你不想弄乱的旧代码,可以继续使用8个空格制表符。

制表符还是空格?

永远不要混合使用制表符和空格。

最常用的缩进Python方式只使用空格。第二种最流行的方式是仅使用制表符。使用制表符和空格的混合缩进的代码应该转换为仅使用空格。当使用-t选项调用Python命令行解释器时,它会发出有关非法混合制表符和空格的警告。当使用-tt时,这些警告变成错误。强烈建议使用这些选项!


13
在Python 2中,TAB的解释就好像它被转换为使用8个空格制表位(如先前的答案所提供的); 即每个TAB将缩进进一步1到8个空格,以便生成的缩进可以被8整除。
然而,在Python 3中不再适用此规则 - 在Python 3混合空格和制表符始终是错误的 - 制表符只匹配制表符,空格只匹配缩进中的其他空格;即使用TABSPACESPACE缩进的块可能包含使用TABSPACESPACETAB缩进的块,但不能包含使用TABTABTAB缩进的块,即使该块似乎延伸得更远也会被视为缩进错误:

如果源文件以混合制表符和空格的方式进行缩进,从而使含义取决于制表符的值,则拒绝缩进不一致;在这种情况下,将引发TabError。

即,算法的工作原理如下:

  • 如果制表符数量和空格数量与上一行匹配(无论顺序如何),则此行属于与上一行相同的块

  • 如果其中一个(制表符或空格)的数量大于上一行的数量,并且另一个的数量至少等于上一行的数量,则这是一个缩进块。

  • 元组 (tabs, spaces) 与先前块中的缩进匹配-将其减少到该块

  • 否则会引发 IndentationError 或 TabError。

这就是为什么在 Python 中混合使用制表符和空格,甚至使用制表符进行缩进都被认为是非常不好的实践。


TAB SPACE SPACE doesn't match SPACE SPACE TAB, it's an IndentationError. The line "if both number of tabs and number of spaces matches the previous line (no matter the order), then this line belongs to the same block" is incorrect; order matters because tabs advance to the next multiple of 8. Python3 doesn't change this, it just disallows substituting tabs with the equivalent number of spaces. - Nick Matteo
@NickMatteo 不确定我是在7年前犯了错误,还是Python 3那时候甚至更“病态”,但即使现在,8个空格+制表符匹配制表符+8个空格。 - Antti Haapala -- Слава Україні
讨论在这里:https://bugs.python.org/issue24260 - Antti Haapala -- Слава Україні

6

只是不要混淆它们 :)
将您的IDE /编辑器设置为在按下“tab”时输入4个空格,然后您就可以开始了。


5
我建议您查看PEP 8,它是Python代码的“官方”风格指南。它涵盖了(除其他事项外)制表符/空格的使用。

2

在我的设置中,四个空格等于一个制表符,但据我所知,它们不能互换。您可以使用空格或制表符,但不能混用。


3
不一定,这取决于你的设置。 - Noufal Ibrahim

-2

我认为在任何情况下,制表符都不应该出现在源代码中。它没有任何优势,而且会引起无尽的小错误。如果需要制表符,请使用带有 \t 的字符字符串,这样有自说明性的优点。

这里是关于制表符与空格的经典文章 - 我在自己的 .emacs 文件中使用了 jwz 的 elisp 变体。

(我承认个人违反了 PEP 8,只使用了 2 个字符的缩进 - 当你的行只有 80 个字符时,4 个字符就太多了...)


1
Douglas Crockford同意(08分49秒)。 - Peter Mortensen
很高兴这条评论又回到了零,曾经是我在这里最被踩的评论。 :-) - Tom Swirly
2
我认为这不符合SO标准问题的实际答案。它完全是主观的,没有回答混合制表符/空格会发生什么的问题。 - ChrisGS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接