我有一个 Python 脚本:
if True:
if False:
print('foo')
print('bar')
但是,当我尝试运行我的脚本时,Python 引发了一个 IndentationError
:
File "script.py", line 4
print('bar')
^
IndentationError: unindent does not match any outer indentation level
我一直在玩我的程序,总共产生了四个错误:
IndentationError: unexpected indent
IndentationError: expected an indented block
TabError: inconsistent use of tabs and spaces in indentation
IndentationError: unindent does not match any outer indentation level
这些错误是什么意思?我究竟做错了什么?我该如何修复我的代码?
注意: 这是对 规范问题 的尝试,因为我每个月都会看到很多类似的帖子。这不是关于 未缩进 或 意外缩进 的现有问题的重复,因为它们每个只处理一种类型的缩进错误,我希望在一个地方涵盖所有这些问题。
也可能出现 逻辑上 不正确的缩进, 但不会 导致出现错误消息。 One common form of this is attaching else:
to a for
or while
loop rather than (as intended) the corresponding if:
.如果您需要关闭 OP 所做的问题,请参阅 Python while 语句中的 Else 子句。
原文由 Christian Dean 发布,翻译遵循 CC BY-SA 4.0 许可协议
为什么缩进很重要?
在 Python 中,缩进用于分隔 代码块。这不同于许多其他使用大括号
{}
来分隔块的语言,例如 Java、Javascript 和 C。因此,Python 用户必须密切注意他们何时以及如何缩进代码,因为空格事项。当 Python 遇到程序缩进问题时,它会引发名为
IndentationError
或TabError
的异常。一点历史
Python 使用缩进与可以说更普遍接受的花括号的历史原因
{}
在 Python 的创造者 Guido van Rossum 的 Python 历史文章中 概述:如何缩进我的代码?
缩进 Python 代码的基本规则(考虑到您将整个程序视为“基本块”)是:基本块中的第一条语句及其后的每个后续语句必须缩进相同的量。
所以从技术上讲,以下 Python 程序是正确的:
然而,正如您可能从上面看出的那样,随机缩进您的代码使得阅读和遵循程序流程变得非常困难。最好保持一致并遵循一种风格。
PEP 8——Python 风格指南——说:
也就是说, 开始新块的每个语句和新块中的每个后续语句都应从当前缩进级别缩进四个空格。以下是根据 PEP8 风格指南缩进的上述程序:
我还能使用标签吗?
Python 意识到有些人仍然更喜欢制表符而不是空格,并且遗留代码可能使用制表符而不是空格,因此它允许使用制表符作为缩进。 PEP8 涉及到这个话题:
但是请注意,一个重要的警告是 不要同时使用制表符 和 空格进行缩进。这样做会导致各种奇怪的难以调试的缩进错误。 Python 将制表符扩展到下一个第 8 列,但是如果您的编辑器将制表符大小设置为 4 列,或者您使用空格和制表符,您可以轻松地生成在编辑器中 看起来 不错的缩进代码,但 Python 会拒绝跑步。 Python 3 编译器 明确 拒绝任何包含制表符和空格的模糊混合的程序,通常是通过引发
TabError
。然而,默认情况下,Python 2 仍然允许混用制表符和空格,但强烈建议不要使用此“功能”。使用-t
和-tt
命令行标志强制 Python 2 分别发出警告或(最好)错误。 PEP8 也讨论了这个话题:“IndentationError:意外缩进”是什么意思?
问题
当语句不必要地缩进或其缩进与同一块中先前语句的缩进不匹配时,会发生此错误。例如,下面程序中的第一条语句不必要地缩进:
在此示例中,
if
块中的can_drive = True
行与任何先前语句的缩进不匹配:使固定
此错误的修复是首先确保有问题的行甚至需要缩进。例如,上面使用
print
的示例可以通过取消缩进来修复:但是,如果您确定该行确实需要缩进,则缩进需要与同一块中前一条语句的缩进相匹配。在上面使用
if
的第二个示例中,我们可以通过确保带有can_drive = True
if
身体:“IndentationError: expected an indented block”是什么意思?
(这也可能在 Python 3.8 或更低版本中作为
SyntaxError: unexpected EOF while parsing
出现。)问题
当 Python 看到复合语句的“标头”时会发生此错误,例如
if <condition>:
或while <condition>:
但从未定义复合语句的主体或 块。例如,在下面的代码中,我们开始了一个if
语句,但我们从未为该语句定义主体:在第二个示例中,我们开始编写
for
循环,但我们忘记缩进for
循环体。所以 Python 仍然需要for
循环体的缩进块:评论不算作正文:
使固定
解决此错误的方法是简单地包含复合语句的主体。
如上所示,新用户的一个常见错误是他们忘记缩进正文。如果是这种情况,请确保要包含在复合语句正文中的每个语句都缩进到复合语句开头下方的同一级别。这是上面的示例修复:
另一种常见情况是,出于某种原因,用户可能不想为复合语句定义实际主体,或者主体可能被注释掉。在这种情况下,可以使用
pass
语句。pass
语句可以在 Python 期望一个或多个语句作为占位符的任何地方使用。 从pass
的文档中:if True: pass pass # oops! this statement should be indented!. else: pass
Traceback (most recent call last): File “python”, line 4 else: ^ SyntaxError: invalid syntax
”`
虽然 Python 提出了一个
SyntaxError
,但上面代码的 真正 问题是第二个pass
语句应该缩进。因为第二个pass
没有缩进,Python 没有意识到前面的if
语句和else
语句意味着连接。解决此类错误的方法是简单地正确地重新缩进您的代码。要了解如何正确缩进代码,请参阅 如何缩进代码? .
我仍然很难使用 Python 的缩进语法。我该怎么办?
如果你还在挣扎,不要气馁。习惯 Python 的空格语法规则可能需要时间。以下是一些有用的提示:
使用的资源