跟光磊学Python开发

跟光磊学Python开发-异常机制

原创ittimeline2021-02-15 17:21:45

异常概述

异常指的是不正常,也就是程序在执行过程中发生了不可预知的问题,导致程序崩溃。
Python中常见的异常类如下,它们都直接或者间接继承自位于builtins.py文件中的Exeption类

  • NameError
  • TypeError
  • ValueError
  • AttributeError
  • SyntaxError
  • IndexError

异常处理

在日常开发中应该尽量避免异常出现,而程序中可能发生异常的情况,可以通过Pyhton提供的异常处理机制来处理异常,从而提高程序的容错性。

异常处理的语法格式为

try:可能发生异常的代码except Exception:当异常发生时,处理异常的代码

例如当使用字符串的index(self, sub, start=None, end=None):方法来查找子串时,如果指定的子串找不到会抛出一个ValueError异常

此时可以使用try/except来处理ValueError的异常,如果异常的类型不确定时可以使用Exception替换,例如这里的ValueError可以使用Exception替换,因为异常都直接或者间接继承Exception

'''使用try/except基本异常处理@author tony 18601767221@163.com@version 2021-02-15 15:38:20@since python3.9.1'''s = 'hello'# 使用try来尝试执行可能发生异常的代码try:    # ValueError: substring not found    i = s.index('O')    print(i)# 如果发生异常,那么异常信息会被except捕捉到,可以在except后面进行异常处理,如果没有发生异常,程序正常运行,而except就不会执行except ValueError:    print('查找的子串不存在')

程序运行结果

项目运行过程中可能会发生多个异常,此时可以将多个异常包装成一个元祖。需要注意的是同一时刻只能有一个异常发生,因为只要有一个异常发生,程序不会再往下执行,转而执行except的异常处理的代码。

try:可能发生异常的代码except (异常1,异常2....)as e:当异常发生时,处理异常的代码

其中as e表示给异常起别名

'''多异常处理@author tony 18601767221@163.com@version 2021-02-15 16:09:54@since python3.9.1'''try:    number / 0except(ZeroDivisionError, NameError) as e:    print('程序出现了异常', e)

程序运行结果

而异常处理的完整语法格式,其中else和finally都是可选的,而finally通常是操作文件、数据库或者网络时关闭资源使用

try:可能出现异常的代码except Exception as e:异常处理的代码else:没有出现异常的代码finally:无论是否出现异常,都会执行此语句块

异常处理之 try/except/else/finally:文件不存在异常

'''异常处理之 try/except/else/finally@author tony 18601767221@163.com@version 2021-02-15 16:16:37@since python3.9.1'''try:    f = None    f = open('java.txt', 'r')except Exception as e:    print('要打开的文件不存在')    print('异常信息是', e)else:    content = f.read(1024)    print('文件内容是', end='\t')    print(content)finally:    print('无论程序是否有异常都会执行finally')    if f != None:        print('关闭文件资源')        f.close()

程序运行结果

异常处理之 try/except/else/finally:文件存在并关闭文件资源

'''异常处理之 try/except/else/finally@author tony 18601767221@163.com@version 2021-02-15 16:16:37@since python3.9.1'''try: f = None f = open('python.txt', 'r')except Exception as e: print('要打开的文件不存在') print('异常信息是', e)else: content = f.read(1024) print('文件内容是', end='\t') print(content)finally: print('无论程序是否有异常都会执行finally') if f != None: print('关闭文件资源') f.close()

程序运行结果

异常传递

当代码出现多个层级调用时,其中如果某个环节发生了异常,但是该异常没有处理,默认情况下该异常会向上抛出,如果上层也没有处理,那么会继续再向上层抛出,直到抛到解释器,解释器默认的处理方式就是中断程序,将异常信息打印输出到终端上。

'''异常传递@author tony 18601767221@163.com@version 2021-02-15 15:59:32@since python3.9.1'''def func_a():    print('execute func_a function')    func_b()def func_b():    print('execute func_b function')    func_c()def func_c():    print('execute func_c function')    result = 1 / 0    print(result)func_a()

程序运行结果

此时推荐在func_c()方法处理该异常

'''异常传递@author tony 18601767221@163.com@version 2021-02-15 15:59:32@since python3.9.1'''def func_a(): print('execute func_a function') func_b()def func_b(): print('execute func_b function') func_c()def func_c(): print('execute func_c function') try: result = 1 / 0 print(result) except ZeroDivisionError: print('0不能作为被除数')func_a()

程序运行结果

当然由于异常的传递机制,也可以在func_b()方法或者是func_a()方法来处理异常

'''异常传递@author tony 18601767221@163.com@version 2021-02-15 15:59:32@since python3.9.1'''def func_a():    print('execute func_a function')    func_b()def func_b():    print('execute func_b function')    try:        func_c()    except ZeroDivisionError:        print('0不能作为被除数')def func_c():    print('execute func_c function')    result = 1 / 0    print(result)func_a()

程序运行结果

自定义异常

在业务开发时需要根据对应的业务场景来自定义相关的业务异常。

自定义异常的语法格式

class 异常名Error(Exception):pass

自定义异常

'''定义一个手机号不是纯数字异常'''class PhoneNumberNotDigitError(Exception):    pass'''定义一个手机号长度不合法异常'''class PhoneNumberLengthError(Exception):    def __init__(self, msg):        self.__msg = msg    def __str__(self):        return self.__msg    pass

系统异常通常是由系统抛出,而自定义异常通常由开发人员手动抛出,其方式是 raise 异常对象,异常对象可以是类对象,也可以是实例对象

def get_phone_number(): ''' 从键盘获取用户输入的手机号,判断是否合法 :return: ''' phone_number = input('请输入一个11位数字的手机号:') if phone_number.isdigit() == False: # 抛出自定义的异常 异常对象是类对象 raise PhoneNumberNotDigitError elif len(phone_number) != 11: # 抛出自定义异常,异常对象是实例对象 raise PhoneNumberLengthError('异常信息:手机号长度必须是11位') return phone_number

通过导入模块调用get_phone_number()函数来处理自定义异常

'''处理自定义异常@author tony 18601767221@163.com@version 2021-02-15 16:49:50@since python3.9.1'''from custom_exception import *# 处理调用get_phone_number()函数时可能发生的异常try:    phone_number = get_phone_number()except (PhoneNumberLengthError, PhoneNumberNotDigitError) as e:    print(e)else:    print('你输入的手机号是', phone_number)

程序运行结果

收藏
举报
2 条评论
(0)

相关推荐