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

Posted

技术标签:

【中文标题】Python对缩进制表符和空格的解释【英文标题】:Python's interpretation of tabs and spaces to indent 【发布时间】:2011-01-03 07:40:45 【问题描述】:

我决定学习一点 Python。第一个介绍说它使用缩进来分组语句。虽然最好的习惯显然是只使用其中一种,但如果我互换它们会发生什么?多少个空格将被视为等于一个制表符?或者如果混合使用制表符和空格,它会完全不起作用吗?

【问题讨论】:

【参考方案1】:

空格不被视为等同于制表符。以制表符缩进的行与以 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 在comment 中指出的那样,在 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 on Indentation Python 3 on Indentation

Python 2 说:

首先,制表符被替换为(从左到右)一到八个空格,这样直到替换的字符总数(包括替换)是八的倍数(这与 Unix 使用的规则相同) )。第一个非空白字符之前的空格总数决定了行的缩进。缩进不能使用反斜杠分割成多条物理行;第一个反斜杠之前的空格决定缩进。

Python 3 说:

制表符被一到八个空格替换(从左到右),这样直到替换的字符总数(包括替换)是八的倍数(这与 Unix 使用的规则相同)。第一个非空白字符之前的空格总数决定了行的缩进。缩进不能使用反斜杠分割成多条物理行;第一个反斜杠之前的空格决定缩进。

(除了开头的单词“First”之外,它们是相同的。)

Python 3 增加了一个额外的段落:

如果源文件混合制表符和空格的方式使含义取决于空格中制表符的价值,则缩进会被拒绝;在这种情况下会引发 TabError。

这意味着在 Python 2 中工作的 TAB 与 8-space 示例将在 Python 3 中生成 TabError。最好(在 Python 3 中是必需的)确保字符序列块中每一行的缩进是相同的。 PEP8 表示“每个缩进级别使用 4 个空格”。 (Google 的编码标准说“使用 2 个空格”。)

【讨论】:

@JonathanLeffler 是的,从“后面跟着一个段落”开始的附录:特别表示标签的大小无关紧要,一个标签只匹配缩进中的一个标签;一个空格只匹配缩进中的一个空格。 仅,行显示在缩进 8 个空格的回溯中。 答案中引用的python3“额外段落”听起来不错,但实际上似乎并没有那样工作。可以在pastebin.com/q6F8Fj0h 看到一个反例(但您必须在每个 LF 之前删除 CR)。它会在制表位 1 处缩进一种方式,在制表位 2 处缩进另一种方式。但是 python 3.6 和 python 3.7 不会拒绝它;它运行得很好。【参考方案2】:

关注PEP 8 了解 Python 风格。 PEP 8 说: 缩进

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

对于您不想弄乱的非常旧的代码,您可以继续 使用 8 格制表符。

制表符还是空格?

切勿混合制表符和空格。

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

【讨论】:

【参考方案3】:

在 Python 2 中,TAB 的解释就像是使用 8 空格制表位将其转换为空格(如先前的答案已提供的那样);也就是说,每个 TAB 将缩进进一步增加 1 到 8 个空格,这样生成的缩进可以被 8 整除。

然而,这不再适用于 Python 3 - 在Python 3 mixing of spaces and tabs are always an error - 制表符仅匹配制​​表符,空格仅匹配缩进中的其他空格;以 TABSPACESPACE 缩进的块可能包含以 TABSPACE 缩进的块kbd>SPACETAB,但没有一个缩进TABTABTAB,它将被视为缩进错误,即使该块似乎会进一步扩展:

如果源文件混合制表符和空格的方式使含义取决于空格中制表符的价值,则缩进会被拒绝;在这种情况下会引发 TabError。

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

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

如果(制表符,空格)之一的数量大于上一行,而另一个的数量至少等于上一行,则这是一个缩进块

元组 (tabs, spaces) 匹配前一个块的缩进 - 这缩进到那个块

否则会引发IndentationErrorTabError

这就是为什么在 Python 中混合使用制表符和空格,甚至使用制表符进行缩进会被认为是一种非常糟糕的做法。

【讨论】:

TAB SPACE SPACE 与 SPACE SPACE TAB 不匹配,这是一个 IndentationError。 “如果制表符数和空格数都与前一行匹配(无论顺序),则该行属于同一块”这行不正确;顺序很重要,因为制表符前进到 8 的下一个倍数。Python3 不会改变这一点,它只是不允许用相同数量的空格替换制表符。 @NickMatteo 不确定我 7 年前是否犯了一个错误,或者 Python 3 是否在当时更多被破坏了,但即使是现在,8 个空格+ tab 匹配 tab + 8 个空格 在这里讨论:bugs.python.org/issue24260【参考方案4】:

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

【讨论】:

【参考方案5】:

我建议您阅读PEP 8,这是 Python 代码的“官方”Python 样式指南。它包括(除其他外)制表符/空格的使用。

【讨论】:

【参考方案6】:

四个空格是一个标签(在我的设置中),但据我所知,它们没有互换。您可以使用空格或制表符,不能同时使用。

【讨论】:

不一定。这取决于您的设置。【参考方案7】:

我相信制表符在任何情况下都不应该出现在源代码中。它没有任何优势,而且它是无穷无尽的微小错误的来源。 - 如果您需要一个制表符,请使用带有 \t 的字符串,它的优点是它是自记录的。

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

(我承认我个人仅使用 2 个字符的缩进就打破了 PEP 8 - 当您的行只有 80 个字符时,4 个字符就很多了......)

【讨论】:

Douglas Crockford agrees(08 分 49 秒)。 很高兴在这条评论上恢复到零,这有一段时间是我在这里投票最多的评论。 :-)

以上是关于Python对缩进制表符和空格的解释的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse:使用制表符和空格进行缩进

python学习:缩进

emacs 修复 python 的制表符缩进

text 缩进中不一致使用制表符和空格

TabError:缩进中制表符和空格的使用不一致 - 集成 MailChimp Django

如何强制 Sublime Text 每个制表符缩进两个空格?