[阶段一] 11. Python异常处理机制

python异常处理机制

  • 什么是异常与异常处理?

python 程序的执行过程中,当发生错误时会引起一个事件,该事件被称为异常。异常会打断程序的正常执行流程。

异常就是错误,异常会导致程序崩溃并停止运行。因此就需要异常处理,能监控并捕获到异常,将异常部位的程序进行修理使得程序继续正常运行。

在 python 中,异常处理是通过 try ... except 语句来完成的。

  • try ... except 语句:
try:
    可能产生异常的代码块
except:
    处理异常的代码块

示例:

# coding:utf-8

try:
    print('try:')
    100/0
    print('never reach here')
except:
    print('except:')
    print('0 不能作为除数')

结果:

try:
except:
0 不能作为除数
  • 处理指定类型的异常:

except 关键字后加上异常类型,表示仅处理该类型的异常。

try:
    可能产生异常的代码块
except 异常类型:
    处理异常的代码块

示例:

# coding:utf-8

try:
    print('try:')
    100/0
    print('never reach here')
except ZeroDivisionError:
    print('except ZeroDivisionError:')

结果:

try:
except ZeroDivisionError:
  • 处理多种类型的异常:

可以使用多个 except 关键字处理多种类型的异常。

try:
    可能产生异常的代码块
except 异常类型1:
    处理异常的代码块
except 异常类型2:
    处理异常的代码块
...

示例:

# coding:utf-8
import random


def generate_error():
    number = random.randint(0, 1)
    if number == 0:
        100 / 0
    else:
        file = open('none-exist-file')


try:
    print('try:')
    generate_error()
    print('never reach here')
except ZeroDivisionError:
    print('except ZeroDivisionError:')
except IOError:    
    print('except IOError:')

根据随机数的不同,结果可能是 except ZeroDivisionErrorexcept IOError:

  • 捕获通用异常:

在捕获异常时,不仅可以获取异常类型,还可以获取异常对象。在不确定是哪种异常的情况下,可以使用 except Exception as e 捕获通用异常。

try:
    可能产生异常的代码块
except Exception as e:
    处理异常的代码块

示例:

# coding:utf-8
import random


def generate_error():
    number = random.randint(0, 1)
    if number == 0:
        100 / 0
    else:
        file = open('none-exist-file')


try:
    print('try:')
    generate_error()
    print('never reach here')
except Exception as e:
    print(e)

这次是将异常对象打印出来,结果可能是 division by zero[Errno 2] No such file or directory: 'none-exist-file'

  • 捕获具体异常:

在捕获异常时,不仅可以获取异常类型,还可以获取异常对象。在确定是哪种异常的情况下,可以使用 except 异常类型 as e 捕获具体的异常。

try:
    可能产生异常的代码块
except 异常类型1 as e:
    处理异常的代码块
except 异常类型2 as e:
    处理异常的代码块
...

try:
    可能产生异常的代码块
except (异常类型1, 异常类型2, ...) as e:
    处理异常的代码块

示例:

# coding:utf-8
import random


def generate_error():
    number = random.randint(0, 1)
    if number == 0:
        100 / 0
    else:
        file = open('none-exist-file')


try:
    print('try:')
    generate_error()
    print('never reach here')
except (ZeroDivisionError, IOError) as e:
    print(e)

这次是将异常对象打印出来,结果可能是 division by zero[Errno 2] No such file or directory: 'none-exist-file'

捕获具体异常时,即使定义了 try ... except,但如果异常类型没有与 except 指定的具体异常类型对应上,程序仍然会停止运行。

  • 常用异常类型:

Exception 是通用异常类型的基类。

异常类型 说明
Exception 通用异常类型(基类)
ZeroDivisionError 不能整除 0
AttributeError 对象没有这个属性
IOError 输入输出操作失败
IndexError 没有当前索引
KeyError 映射中没有这个键
NameError 未声明/初始化对象
FileNotFoundError 文件不存在
ModuleNotFoundError 模块不存在
SyntaxError Python语法错误
IndentationError 缩进错误
AssertionError 断言语句失败
SystemError 系统错误
ValueError 传入的参数错误
TypeError 类型错误
  • try ... else 语句:

在异常处理中,else 关键字用于指定没有异常时执行的代码块。当异常发生时,该代码块不会被执行;

try:
    可能产生异常的代码块
except:
    处理异常的代码块
else:
    没有异常时执行的代码块

示例:

# coding:utf-8

try:
    file = open('test.txt')
    line = file.readline()
except IOError:
    print('except IOError:')
else:
    print(line)
    file.close()

结果:

except IOError:
  • try ... finally 语句:

在异常处理中,finally 关键字后面的代码是无论是否发生异常,都一定会执行的代码。

在函数中,即使在 tryexcept 中进行了 returnfinally 中的代码仍然会执行。而且,try 语法至少要有 exceptfinally 中的一个来配合使用。

如果函数中的 tryexceptfinally 都有 return,最终会返回 finally 中的 return 指定的返回值。

try:
    可能产生异常的代码块
except:
    处理异常的代码块
finally:
    无论是否发生异常都会执行的代码块

示例:

# coding:utf-8

def test():
    try:
        100 / 0
    except Exception as e:
        print('111')
        return e
    finally:
        return 'finally'


print(test())

结果:

111
finally
  • 自定义异常与主动抛出异常:

在 python 中,自定义抛出异常的关键字是 raiseraise 关键字可以将信息以报错的形式主动抛出。

raise 语句有 3 种形式:

形式 功能
raise 不带任何参数
raise Exception 把异常的名称作为参数
raise Exception(info) 把异常的名称、异常的描述信息作为参数

示例:

# coding:utf-8

def test(number):
    if number == 100:
        raise ValueError('number 不可以是 %s' % number)
    return number


def test2(number):
    try:
        return test(number)
    except ValueError as e:
        print(e)


test2(100)

结果:

number 不可以是 100
  • 自定义异常类:

自定义异常类需要继承 Exception 基类,而且要在构造函数中定义错误信息。

class 自定义异常类名(Exception):
    def __init__(self, message):
        self.message = message

示例:

# coding:utf-8

class NumberLimitError(Exception):
    def __init__(self, message):
        self.message = message


def test(number):
    if number > 100:
        raise NumberLimitError('number 不可以超过 %s' % number)
    return number


def test2(number):
    try:
        return test(number)
    except NumberLimitError as e:
        return e


print(test2(100))
print(test2(200))

结果:

100
number 不可以超过 200
  • 断言

断言用于判断一个表达式,在表达式条件为 False 时触发异常。

在 python 中,断言的关键字是 assertassert 表示假定表达式为 True,不执行任何操作,为 False 时即触发异常。

raise 不同,raise 是直接抛出异常,而 assert 会进行判断,当判断结果为 False 时才会抛出异常。

用法:

assert expression, message

参数 expression 表示表达式,一般是判断相等或判断某种数据类型的语句,message 表示具体的错误信息,assert 无返回值。

示例:

# coding:utf-8

class NumberLimitError(Exception):
    def __init__(self, message):
        self.message = message


def test(number):
    assert number <= 100, NumberLimitError('number 不可以超过 %s' % number)
    return number


print(test(100))
print(test(200))

结果:

100
AssertionError: number 不可以超过 200
  • bug:

bug 是程序中出现的错误,但又没有通过异常去捕获,以至于直接抛出,导致程序的崩溃。


Guess you like

Origin blog.csdn.net/miss1181248983/article/details/120186713