ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

16 异常与断言

什么是异常?

Python的运行时错误称作异常。Python异常是一个对象,表示错误或意外发生。

异常分为:

  • 语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译。
  • 逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成、计算或输出结果需要的过程无法执行等。

Python的异常默认处理方式则是:终止应用程序,并打印提示信息;

当Python检测到一个错误时,将触发一个异常。Python可以通过异常传导机制传递给一个异常对象,发出一个异常情况出现的信号。Python程序员也可以在代码中手动触发异常来实现控制流的控制。

异常捕获

常用格式:

try:
    pass    # 主代码块
except Exception as e:
		pass    # 任何异常时,执行该块
……    		#try-except语句执行完后,继续执行其他语句

其他格式:

try-exceptexcept可多个
try-finally
try-except-else
try-except-finally
try-except-else-finally

完整格式:

try:
    pass    #主代码块,遇到异常,中断当前代码段,跳转到except
except KeyError as e:
		pass    # KeyError异常时,执行该块
...省略其他的except依次捕获...
except Exception as e:
    pass    # Exception异常时,执行该块。等同于except:捕获一切异常
except:		#捕获一切异常
     pass   #Other exception handle,except块是可选项,如果没有提供,该exception将会被提交给python进行默认处理,默认处理方式则是终止应用程序并打印提示信息;
else:
    pass    # 没有异常时,执行该块
finally:
    pass    # 无论异常与否,最终执行该块
pass

主动触发异常

对异常进行捕获处理:

try:
    pass
    raise Exception('错误了。。。')   #创建Exception对象(封装了错误信息)
except Exception as e:
print(e)
#后面的语句继续执行

对异常不进行捕获处理:

raise Exception('错误了。。。')   #创建Exception对象(封装了错误提示信息)。如果不适用exxcept进行一场捕获,则采用异常默认处理方式则是:终止应用程序(后面的语句不再执行),并打印提示信息;

自定义异常

class MyException(Exception):  #继承父类Exception
    def __init__(self, msg):
        self.message = msg

    def __str__(self):
        return self.message

try:
    raise MyException('我的异常')
except MyException as e:
    print(e)

标准异常介绍

Python自身引发的所有异常都是 Exception的子类的实例。

大多的标准异常都是由 StandardError派生的,其有3个抽象的子类

  • ArithmeticError:

    • 由于算术错误而引发的异常基类

    • OverflowError, ZeroDivisionError, FloatingPointError

  • LookupError

    • 容器在接收到一个无效键或索引时引发的异常的基类
    • IndexError,KeyError
  • EnvironmentError

    • 由于外部原因而导致的异常的基类
    • IOError, OSError, WindowsError

标准异常:(标准模块中引发的异常)

AssertionError:断言语句失败

AttributeError:属性引用或赋值失效

FloatingPointError:浮点型运算失败

IOError:I/O操作失败

ImportError:import语句不能找到要导入的模块或者不能找到该模块特别请求的名称

IndentationError:解析器遇到了一个由于错误的缩进而引发的语法错误

IndexError:用来索引序列的整数超出了范围

KeyError:用来索引映射的键不在映射中

KeyboardInterrupt:用户按了中断键(CtrI+c, Ctrl+Break或Delete键)

MemoryError:运算耗尽内存

NameError:引用了一个不存在的变量名

NotImplementedError:由抽象基类引发的异常;用于指示有个具体的子类必须覆盖一个方法

OSError:由模块os中的函数引发的异常,用来指示平台相关的错误

OverflowError:整数运算的结果太大导致溢出

SyntaxError:语法错误

SystemError:Python本身或某些扩展模块中的内部错误

TypeError:对某对象执行了不支持的操作

UnboundLocalError:引用未绑定值的本地变量

UnicodeError:在Unicode的字符串之间进行转换时发生的错误

ValueError:应用于某个对象的操作或函数,这对象具有正确的类型,但却有不适当的值

WindowsError:模块os中的函数引发的异常,用来指示与Windows相关的错误

ZeroDivisionError:除数为0

示例:

try:
    self._sync(self._src_mc)  #写一个死循环,然后一直运行
except exceptions.KeyboardInterrupt:   #直到用户ctrl+c手动终止
    self._logger.info('terminating...')

断言

Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。

断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。常用于在程序中引入调试代码。

语法格式如下:

assert expression

等价于:

if not expression:
    raise AssertionError

assert 后面也可以紧跟参数:

如果expression为true,则assert不做任何操作。

如果expression为false,则assert使用arguments作为参数,实例化AssertionError并引发。

assert expression [, arguments]

等价于:

if not expression:
    raise AssertionError(arguments)

注意:如果运行Python时使用了-O优化选项,则assert将是一个空操作:编译器不为assert语句生成代码。

运行Python时不使用-O选项,则__debug__ 内置变量为True, 否则其值为False。以上等价于:

if __debug__:
    if not expression:
        raise AssertionError(arguments)

以下为 assert 使用实例:

>>> assert True     # 条件为 true 正常执行
>>> assert False    # 条件为 false 触发异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1==1    # 条件为 true 正常执行
>>> assert 1==2    # 条件为 false 触发异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

>>> assert 1==2, '1 不等于 2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: 1 不等于 2
>>>

以下实例判断当前系统是否为 Linux,如果不满足条件则直接触发异常,不必执行接下来的代码:

import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"

# 接下来要执行的代码