避免缩进错误

Python 使用缩进来确定一行或一组行与程序其余部分的关系。 在前面的示例中,向各个魔术师打印消息的行是 for 循环的一部分,因为它们是缩进的。 Python 使用缩进使代码非常易于阅读。 基本上,它使用空格来强制您编写格式整齐、视觉结构清晰的代码。 在较长的 Python 程序中,您会注意到代码块缩进了几个不同的级别。 这些缩进级别可帮助您对整个程序的组织结构有一个大致的了解。 当您开始编写依赖于正确缩进的代码时,您需要注意一些常见的缩进错误。 例如,人们有时会缩进不需要缩进的代码行,或者忘记缩进需要缩进的代码行。 现在查看这些错误的示例将帮助您在将来避免它们并在它们出现在您自己的程序中时更正它们。 让我们检查一些更常见的缩进错误。

忘记缩进

始终在循环中的 for 语句之后缩进该行。 如果你忘记了,Python 会提醒你:

magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician) (1)
1 对 print() 的调用应该缩进,但事实并非如此。 当 Python 需要一个缩进块但没有找到时,它会让您知道哪一行有问题:
File "magicians.py", line 3
  print(magician)
  ^
IndentationError: expected an indented block after 'for' statement on line 2

您通常可以通过在 for 语句之后立即缩进一行或多行来解决此类缩进错误。

忘记缩进额外的代码行

有时你的循环运行没有任何错误,但不会产生预期的结果。 当您尝试在循环中执行多项任务而忘记缩进其中的某些行时,就会发生这种情况。

例如,当我们忘记缩进循环中的第二行时会发生这种情况,该循环告诉每个魔术师我们期待他们的下一个魔术:

magicians = ['alice', 'david', 'carolina']
for magician in magicians:
    print(f"{magician.title()}, that was a great trick!")
print(f"I can't wait to see your next trick, {magician.title()}.\n") (1)
1 第二次调用 print() 应该是缩进的,但是因为 Python 在 for 语句之后发现至少有一个缩进行,所以不会报错。 结果,第一次 print() 调用对列表中的每个名称执行一次,因为它是缩进的。 第二个 print() 调用没有缩进,所以它只在循环运行结束后执行一次。 因为与 magician 关联的最终值是 'carolina',所以她是唯一收到“期待下一个魔术”消息的人:
Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.

这是一个逻辑错误。 语法是有效的 Python 代码,但是代码没有产生预期的结果,因为它的逻辑出现了问题。 如果您希望看到某个动作对列表中的每个项目重复一次并且只执行一次,请确定您是否需要简单地缩进一行或一组行。

不必要的缩进

如果您不小心缩进了不需要缩进的行,Python 会通知您意外的缩进:

message = "Hello Python world!"
    print(message)

我们不需要缩进 print() 调用,因为它不是循环的一部分; 因此,Python 报告该错误:

File "hello_world.py", line 2
  print(message)
  ^
IndentationError: unexpected indent

您可以通过仅在有特定原因时才缩进来避免意外的缩进错误。 在您此时正在编写的程序中,您唯一应该缩进的行是您要为 for 循环中的每个项目重复的操作。

循环后不必要的缩进

如果您不小心缩进了应该在循环结束后运行的代码,那么该代码将针对列表中的每个项目重复一次。 有时这会提示 Python 报错,但通常这会导致逻辑错误。

例如,让我们看看当我们不小心缩进感谢魔术师作为一个团队进行了一场精彩表演的行时会发生什么:

magicians = ['alice', 'david', 'carolina']
for magician in magicians:
    print(f"{magician.title()}, that was a great trick!")
    print(f"I can't wait to see your next trick, {magician.title()}.\n")
    
    print("Thank you everyone, that was a great magic show!") (1)
1 因为最后一行是缩进的,所以它会为列表中的每个人打印一次:
Alice, that was a great trick!
I can't wait to see your next trick, Alice.

Thank you everyone, that was a great magic show!
David, that was a great trick!
I can't wait to see your next trick, David.

Thank you everyone, that was a great magic show!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.

Thank you everyone, that was a great magic show!

这是另一个逻辑错误,类似于第 54 页的“忘记缩进附加行”中的错误。因为 Python 不知道您要用代码完成什么,所以它将运行所有以有效语法编写的代码。如果某个动作在本应只执行一次的情况下重复多次,您可能需要取消缩进该动作的代码。

遗漏冒号

for 语句末尾的冒号告诉 Python 将下一行解释为循环的开始。

magicians = ['alice', 'david', 'carolina']
for magician in magicians (1)
    print(magician)
1 如果你不小心忘记了冒号,你会得到一个语法错误,因为 Python 并不知道你到底想做什么:
File "magicians.py", line 2
  for magician in magicians
                           ^
SyntaxError: expected ':'

Python 不知道您是否只是忘记了冒号,或者您是否打算编写额外的代码来设置更复杂的循环。 如果解释器可以识别一个可能的修复,它会建议一个,比如在一行的末尾添加一个冒号,就像它在这里对预期的响应 ':' 所做的那样。 由于 Python 的回溯中的建议,一些错误有简单、明显的修复。 有些错误更难解决,即使最终修复只涉及一个字符。 当一个小的修复需要很长时间才能找到时,不要难过; 在这种体验中,您绝对不是一个人。

自己试试
4-1.Pizzas

至少想出三种你最喜欢的披萨。 将这些披萨名称存储在一个列表中,然后使用 for 循环打印每个披萨的名称。 修改您的 for 循环以使用比萨饼的名称打印一个句子,而不是仅打印比萨饼的名称。 对于每个比萨饼,您应该有一行输出包含一个简单的语句,例如我喜欢意大利辣香肠比萨饼。 在程序末尾的 for 循环外添加一行,说明你有多喜欢披萨。 输出应该包括三行或更多行关于你喜欢的披萨种类,然后是一个额外的句子,比如我真的很喜欢披萨!

4-2.Animals

想出至少三种具有共同特征的不同动物。 将这些动物的名字存储在一个列表中,然后使用 for 循环打印出每只动物的名字。 修改您的程序以打印关于每种动物的声明,例如 A dog would make a great pet。 在程序末尾添加一行,说明这些动物的共同点。 您可以打印一句话,例如 Any of these animals would make a great pet!