Python-我收到一个IndentationError我如何解决它?

在Python中,缩进用于分隔代码块。这与许多其他使用花括号{}分隔块的语言(例如Java,Javascript和C)不同。因此,Python用户必须密切注意缩进代码的时间和方式,因为空格很重要。

当Python遇到程序缩进问题时,它会引发一个称为IndentationError或的异常TabError

一点历史

Python 的创建者Guido van Rossum在Python历史上的文章中{}概述了Python使用缩进而不是可能更普遍使用的花括号的历史原因:

Python对缩进的使用直接来自ABC,但是这个想法并非源于ABC,它已经由Donald Knuth提倡,并且是编程风格的著名概念。(occam编程语言也使用了它。)但是,ABC的作者确实发明了使用冒号的方法,该冒号将导入子句与缩进块分开。在没有冒号的早期用户测试之后,发现缩进的含义对于初学者来说尚不清楚,因为他们已经开始学习编程的第一步。冒号的添加大大地澄清了这一点:冒号以某种正确的方式引起人们对后续内容的注意,并将其前后的短语联系在一起。

缩进Python代码的基本规则(考虑到将整个程序视为“基本块”)是:基本块中的第一个语句以及后面的每个后续语句必须缩进相同的数量。

因此从技术上讲,以下Python程序是正确的:

def perm(l):
        # Compute the list of all permutations of l
    if len(l) <= 1:
                  return [l]
    r = []
    for i in range(len(l)):
             s = l[:i] + l[i+1:]
             p = perm(s)
             for x in p:
              r.append(l[i:i+1] + x)
    return r

但是,你可能从上面可以看出,随机地缩进代码会使阅读和遵循程序流程变得非常困难。最好保持一致并遵循一种风格。

PEP8-Python样式指南-建议在每个缩进级别使用四个空格:

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

也就是说,每个开始一个新块的语句以及该新块中的每个后续语句都应从当前缩进级别缩进四个空格。这是根据PEP8样式指南缩进的上述程序:

def perm(l):
    # Compute the list of all permutations of l
    if len(l) <= 1:
        return [l]
    r = []
    for i in range(len(l)):
        s = l[:i] + l[i+1:]
        p = perm(s)
        for x in p:
            r.append(l[i:i+1] + x)
    return r

Python意识到有些人仍然喜欢使用制表符而不是空格,并且遗留代码可能使用制表符而不是空格,因此它允许使用制表符作为缩进。PEP8涉及以下主题:

空格是首选的缩进方法。

制表符应仅用于与已经用制表符缩进的代码保持一致。

但是请注意,最大的警告是不要同时使用制表符和空格进行缩进。这样做会导致各种奇怪的难以调试的缩进错误。Python将制表符扩展到下一个第8列,但是如果将编辑器的制表符大小设置为4列,或者你同时使用空格和制表符,则可以轻松生成缩进的代码,这些代码在编辑器中看起来不错,但是Python会拒绝跑步。Python 3编译器通常通过引发来显式拒绝包含制表符和空格的混合使用的程序TabError。但是,默认情况下,Python 2仍允许混合使用制表符和空格,但是强烈建议不要使用此“功能”。使用-t-tt命令行标志分别强制Python 2发出警告或(最好是)错误。PEP8还讨论了以下主题:

Python 3不允许混合使用制表符和空格进行缩进。

由制表符和空格组成的缩进的Python 2代码应转换为仅使用空格。

当使用-t选项调用Python 2命令行解释器时,它会发出有关非法混合使用制表符和空格的代码的警告。当使用-tt时,这些警告变为错误。强烈建议你使用这些选项!

问题

当语句不必要地缩进或者其缩进与同一块中以前的语句的缩进不匹配时,会发生此错误。例如,以下程序中的第一条语句不必要地缩进:

>>>  print('Hello') # this is indented 
  File "<stdin>", line 1
    print('Hello') # this is indented 
    ^
IndentationError: unexpected indent

在此示例中,块中的can_drive = True行if与任何以前的语句的缩进都不匹配:

>>> age = 10
>>> can_drive = None
>>> 
>>> if age >= 18:
...     print('You can drive')
...      can_drive = True # incorrectly indented
  File "<stdin>", line 3
    can_drive = True # incorrectly indented
    ^
IndentationError: unexpected indent

固定

解决此错误的方法是,首先确保有问题的行甚至需要缩进。例如,上面的示例print可以通过简单地将行缩进来解决:

>>> print('Hello') # simply unindent the line
Hello

但是,如果你确定该行确实需要缩进,则该缩进需要与同一块中先前语句的缩进匹配。在上面使用的第二个示例中if,我们可以通过确保with can_drive = True所在行的缩进与if正文中先前语句的缩进级别来修复错误:

>>> age = 10
>>> can_drive = None
>>> 
>>> if age >= 18:
...     print('You can drive')
...     can_drive = True # indent this line at the same level.
... 

问题

当Python看到复合语句的“标头”(例如if :或,while :但从未定义复合语句的主体或块)时,就会发生此错误。例如,在下面的代码中,我们开始了一条if语句,但是我们从未为该语句定义主体:

>>> if True:
... 
  File "<stdin>", line 2

    ^
IndentationError: expected an indented block

在第二个示例中,我们开始编写一个for循环,但是忘记缩进for循环主体。因此,Python仍然希望for循环体缩进:

>>> names = ['sarah', 'lucy', 'michael']
>>> for name in names:
... print(name)
  File "<stdin>", line 2
    print(name)
        ^
IndentationError: expected an indented block

评论不算作主体:

>>> if True:
...     # TODO
...
  File "<stdin>", line 3

    ^
IndentationError: expected an indented block

固定

解决此错误的方法是简单地为复合语句添加一个主体。

如上所示,新用户的一个常见错误是他们忘了缩进身体。在这种情况下,请确保要包含在复合语句主体中的每个语句在复合语句的开头都缩进相同的级别。这是上面固定的示例:

>>> names = ['sarah', 'lucy', 'michael']
>>> for name in names:
...     print(name) # The for loop body is now correctly indented.
... 
sarah
lucy
michael

另一个常见的情况是,由于某种原因,用户可能不想为复合语句定义实际主体,或者可能会注释掉该主体。在这种情况下,pass可以使用该语句。该pass语句可在Python需要一个或多个语句作为占位符的任何地方使用。从文档中pass:

pass是一个空操作-执行该操作不会发生任何事情。在语法上需要一条语句但不需要执行任何代码时,它可用作占位符,例如:

def f(arg): pass    # a function that does nothing (yet)

class C: pass       # a class with no methods (yet)

这是上面的示例,其中if使用pass关键字修复了该语句:

>>> if True:
...     pass # We don't want to define a body.
... 
>>>

问题

当你取消语句的缩进时会发生此错误,但是现在该语句的缩进级别与任何以前的语句都不匹配。例如,在下面的代码中,我们取消对的第二个调用的缩进print。但是,缩进级别与以前的任何语句都不匹配:

>>> if True:
...     if True:
...         print('yes')
...    print()
  File "<stdin>", line 4
    print()
          ^
IndentationError: unindent does not match any outer indentation level

很难捕获此错误,因为即使一个空格也会导致你的代码失败。

固定

解决方法是确保取消对语句的缩进时,缩进级别与先前的语句匹配。再次考虑上述示例。在示例中,我希望第二个打印要在第一个if语句主体中进行。因此,我需要确保该行的缩进级别与第一条if语句主体中的前一条语句的缩进级别匹配:

>>> if True:
...     if True:
...         print('yes')
...     print() # indentation level now matches former statement's level.
... 
yes

>>> 

我仍然收到IndentationError,但是我的程序似乎正确缩进了。我该怎么办? 如果你的程序在外观上看似具有正确的缩进,但仍能IndentationError看到,则很可能是带有空格的混合制表符。有时这会导致Python引发奇怪的错误。请参阅本节特殊情况下,什么是“TabError:在缩进使用不一致的制表符和空格的”呢?有关该问题的更深入说明。

“ TabError:缩进中的制表符和空格的使用不一致”是什么意思?

问题

仅当你尝试将制表符和空格混合为缩进字符时,才会发生此错误。如上所述,Python将不允许你的程序包含制表符和空格的混合,并且TabError如果发现有异常,将引发特定异常。例如,在下面的程序中,制表符和空格的混合用于缩进:

>>> if True:
...     if True:
...         print()
...     print()
...     print()
  File "<stdin>", line 5
    print()
          ^
TabError: inconsistent use of tabs and spaces in indentation

这是一张图片,直观地显示了上述程序中的空白。灰色点是空格,灰色箭头是标签:

我们可以看到我们确实有混合的空格和缩进制表符。

注意如果将制表符和空格混入程序中,Python 不会 总是产生a TabError。如果程序缩进是明确的,Python将允许制表符和空格混合使用。例如:

>>> if True:
...     if True: # tab
...         pass # tab, then 4 spaces
... 
>>>

有时,Python只是在制表符和空格的混合中使人窒息,并IndentationError在a TabError更合适的情况下错误地引发了异常。另一个例子:

>>> if True:
...     pass # tab
...     pass # 4 spaces
  File "<stdin>", line 3
    pass # 4 spaces
                ^
IndentationError: unindent does not match any outer indentation level

如你所见,以这种方式运行代码会产生神秘的错误。即使该程序在外观上看起来不错,但Python仍在尝试解析用于缩进的制表符和空格并出错时感到困惑。

这些都是出色的示例,这些示例说明了为什么在使用Python 2时永远不要混用制表符和空格并使用-t和-tt解释器标志。

固定

如果你的程序简短,那么最简单,最快的解决方法就是简单地重新缩进该程序。确保每个语句在每个缩进级别缩进四个空格(请参阅如何缩进代码?)。

但是,如果你已经有将制表符和空格混入其中的大型程序,则可以使用自动化工具将所有缩进转换为仅空格。

许多编辑器(例如PyCharm和SublimeText)都具有将制表符自动转换为空格的选项。还有一些在线工具,例如“ 制表符到空格”或“ 浏览器”,可让你快速重新缩进代码。还有一些用Python编写的工具。例如,autopep8可以自动重新缩进你的代码以及其他缩进错误。

即使是最好的工具,有时也无法修复所有的缩进错误,因此你必须手动修复它们。这就是为什么从一开始就始终正确缩进代码很重要的原因。

尽管不经常使用,但有时SyntaxError由于缩进不正确会引起某些例外情况。例如,看下面的代码:

if True:
    pass
pass # oops! this statement should be indented!.
else:
    pass

运行上面的代码后,一个SyntaxError is raised:

Traceback (most recent call last):
  File "python", line 4
    else:
       ^
SyntaxError: invalid syntax

尽管Python提出了a SyntaxError,但是上面的代码的真正问题是第二条pass语句应该缩进。因为第二个pass没有缩进,所以Python并没有意识到前面的if语句和该else语句是要连接的。

解决此类型错误的方法是简单地正确缩进你的代码。要查看如何正确缩进代码,请参见如何缩进代码部分。。

如果你仍在挣扎,不要灰心。使用Python的空白语法规则可能需要一些时间。这里有一些技巧可以帮助你:

  • 获取一个编辑器,该编辑器会在出现缩进错误时告诉你。如上所述,一些商品包括PyCharm,SublimeText和Jupyter Notebook。
  • 缩进代码时,请大声计算自己按空格键(或Tab键)的次数。例如,如果你需要将一行缩进四个空格,你会大声地说“ 一,二,三,四 ”,同时每次按下空格键。听起来很傻,但是它可以帮助你训练大脑思考代码缩进的深度。
  • 如果你有编辑器,请查看它是否具有将制表符自动转换为空格的选项。
  • 查看其他人的代码。浏览github或Stackoverflow并查看Python代码示例。
  • 只需编写代码。那是变得更好的唯一最佳方法。你编写的Python代码越多,你就会获得更好的效果。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Python中的函数(二) 在上一篇文章中提到了Python中函数的定义和使用,在这篇文章里我们来讨论下关于函数的一些更深的话题。在学习C语言函数的时候,遇到的问题主要有形参实参的区别、参数的传递和改变、变量的作用域。同样在Python中,关于对函数的理解和使用也存在这些问题。下面来逐一讲解。一.函
Python中的字符串 可能大多数人在学习C语言的时候,最先接触的数据类型就是字符串,因为大多教程都是以&quot;Hello world&quot;这个程序作为入门程序,这个程序中要打印的&quot;Hello world&quot;就是字符串。如果你做过自然语言处理方面的研究,并且用Python
Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程。下面就来了解一下如何在Python中进行对象编程。一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。 类是对现实世界中一些事物的封装,
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定义和使用方法,这只体现了面向对象编程的三大特点之一:封装。下面就来了解一下另外两大特征:继承和多态。 在Python中,如果需要的话,可以让一个类去继承一个类,被继承的类称为父类或者超类、也可以称作基类,继承的类称为子类。并且Pytho
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非常熟悉,无论在哪门编程语言当中,函数(当然在某些语言里称作方法,意义是相同的)都扮演着至关重要的角色。今天就来了解一下Python中的函数用法。一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明
在windows下如何快速搭建web.py开发框架 用Python进行web开发的话有很多框架供选择,比如最出名的Django,tornado等,除了这些框架之外,有一个轻量级的框架使用起来也是非常方便和顺手,就是web.py。它由一名黑客所创建,但是不幸的是这位创建者于2013年自杀了。据说现在由
将Sublime Text 2搭建成一个好用的IDE 说起编辑器,可能大部分人要推荐的是Vim和Emacs,本人用过Vim,功能确实强大,但是不是很习惯,之前一直有朋友推荐SUblime Text 2这款编辑器,然后这段时间就试了一下,就深深地喜欢上这款编辑器了...
Python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句&quot;#include&lt;math.h&gt;&quot;引入math.h这个头文件,否则是无法正常进行调用的。那么在Python中,如果要引用一些内置的函数,该怎么处理呢?在Python中
Python的基础语法 在对Python有了基础的认识之后,下面来了解一下Python的基础语法,看看它和C语言、java之间的基础语法差异。一.变量、表达式和语句 Python中的语句也称作命令,比如print &quot;hello python&quot;这就是一条语句。 表达式,顾名思义,是
Eclipse+PyDevʽjango+Mysql搭建Python web开发环境 Python的web框架有很多,目前主流的有Django、Tornado、Web.py等,最流行的要属Django了,也是被大家最看好的框架之一。下面就来讲讲如何搭建Django的开发环境。一.准备工作 需要下载的
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便。 Ulipad下载地址: https://github.com/limodou/ulipad http://files.cnblogs.com/dolphin0520/u...
Python中的函数(三) 在前面两篇文章中已经探讨了函数的一些相关用法,下面一起来了解一下函数参数类型的问题。在C语言中,调用函数时必须依照函数定义时的参数个数以及类型来传递参数,否则将会发生错误,这个是严格进行规定的。然而在Python中函数参数定义和传递的方式相比而言就灵活多了。一.函数参数的
在Notepad++中搭配Python开发环境 Python在最近几年一度成为最流行的语言之一,不仅仅是因为它简洁明了,更在于它的功能之强大。它不仅能够完成一般脚本语言所能做的事情,还能很方便快捷地进行大规模的项目开发。在学习Python之前我们来看一下Python的历史由来,&quot;Pytho
Python中的条件选择和循环语句 同C语言、Java一样,Python中也存在条件选择和循环语句,其风格和C语言、java的很类似,但是在写法和用法上还是有一些区别。今天就让我们一起来了解一下。一.条件选择语句 Python中条件选择语句的关键字为:if 、elif 、else这三个。其基本形式如
关于raw_input( )和sys.stdin.readline( )的区别 之前一直认为用raw_input( )和sys.stdin.readline( )来获取输入的效果完全相同,但是最近在写程序时有类似这样一段代码:import sysline = sys.stdin.readline()
初识Python 跟学习所有的编程语言一样,首先得了解这门语言的编程风格和最基础的语法。下面就让我们一起来了解一下Python的编程风格。1.逻辑行与物理行 在Python中有逻辑行和物理行这个概念,物理行是指在编辑器中实际看到的一行,逻辑行是指一条Python语句。在Python中提倡一个物理行只
当我们的代码是有访问网络相关的操作时,比如http请求或者访问远程数据库,经常可能会发生一些错误,有些错误可能重新去发送请求就会成功,本文分析常见可能需要重试的场景,并最后给出python代码实现。
1.经典迭代器 2.将Sentence中的__iter__改成生成器函数 改成生成器后用法不变,但更加简洁。 3.惰性实现 当列表比较大,占内存较大时,我们可以采用惰性实现,每次只读取一个元素到内存。 或者使用更简洁的生成器表达式 4.yield from itertools模块含有大量生成器函数可
本文介绍简单介绍socket的常用函数,并以python-kafka中的源码socketpair为例,来讲解python socket的运用
python实践中经常出现编码相关的异常,大多网上找资料而没有理解原理,导致一次次重复错误。本文对常用Unicode、UTF-8、GB2312编码的原理进行介绍,接着介绍了python字符类型unicode和str以及常见编解码错误UnicodeEncodeError和UnicodeDEcodeEr