Python进阶12-异常问题2

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

来源:《Python从小白到大牛》关东升

1、捕获异常

在面对异常时,当前函数有能力解决,则捕获异常进行处理;没有能力解决,则抛给上层调用者(函数)处理。如果上层调用者还无力解决,则继续抛给它的上层调用者。异常就是这样向上传递直到有函数处理它。如果所有函数都没有处理该异常,那么Python解释器会终止程序运行。这就是异常的传播过程。

1.1 try-except语句

捕获异常是通过try-except语句实现的,最基本的try-except语句语法如下:

    try:
        <可能会抛出异常的语句>
    except [异常类型]:
        <处理异常>

1)try代码块
try代码块中包含执行过程中可能会抛出异常的语句。
2)except代码块
每个try代码块可以伴随一个或多个except代码块,用于处理try代码块中所有可能抛出的多种异常。except语句中如果省略“异常类型”,即不指定具体异常,则会捕获所有类型的异常;如果指定具体类型异常,则会捕获该类型异常,以及它的子类型异常。

1.2多except代码块

如果try代码块中有很多语句抛出异常,而且抛出的异常种类有很多,那么可以在try后面跟有多个except代码块。多except代码块语法如下:

try:
    <可能会抛出异常的语句>
except [异常类型I]:
    <处理异常>
except [异常类型II]:
    <处理异常>
...
except [异常类型n]:
    <处理异常>

在多个except代码情况下,当一个except代码块捕获到一个异常时,其他的except代码块就不再进行匹配。

注意:当捕获的多个异常类之间存在父子关系时,捕获异常顺序与except代码块的顺序有关。从上到下先捕获子类,后捕获父类。否则子类捕获不到。

1.3try-except语句嵌套

Python提供了try-except语句是可以任意嵌套的。程序执行时如果内层抛出异常,首先由内层except进行捕获,如果捕获不到,则由外层except捕获。

注意:try-except不仅可以嵌套在try代码块中,还可以嵌套在except代码块或finally代码块,finally代码块后面会详细介绍。try-except嵌套会使程序流程变得复杂,如果能用多except捕获的异常,尽量不要使用try-except嵌套。要梳理好程序的流程再考虑try-except嵌套的必要性。

1.4多重异常捕获

多个except代码块客观上提高了程序的健壮性,但是也大大增加了程序代码量。有些异常种类不同,当捕获之后的处理是相同的。

try:
    <可能会抛出异常的语句>
except ValueError as e:
    <调用方法method处理>
except OSError as e:
    <调用方法method处理>
except FileNotFoundError as e:
    <调用方法method处理>

三个不同类型的异常,要求捕获之后的处理都是调用method方法。是否可以把这些异常合并处理呢?Python中可以把这些异常放到一个元组中,这就是多重异常捕获,可以帮助解决此类问题。

    # coding=utf-8
    import datetime as dt

    def read_date_from_file(filename):
        try:
            file=open(filename)
            in_date=file.read()
            in_date=in_date.strip()
            date=dt.datetime.strptime(in_date,'%Y-%m-%d')
            return date
        except (ValueError,OSError) as e:
            print('调用方法method1处理...')
            print(e)

代码中(ValueError,OSError)就是多重异常捕获。

2、异常堆栈跟踪

有时从程序员的角度需要知道更加详细的异常信息时,可以打印堆栈跟踪信息。堆栈跟踪信息可以通过Python内置模块traceback提供的print_exc()函数实现,print_exc()函数的语法格式如下:

    traceback.print_exc(limit=None,file=None,chain=True)

其中,参数 limit 限值堆栈跟踪的个数,默认 None 是不限制;参数 file 判断是否输出堆栈跟踪信息到文件,默认 None 是不输出到文件;参数 chain 为 True ,则将__cause__和__context__等属性串联起来,就像解释器本身打印未处理异常一样打印。

提示:在捕获到异常之后,通过print_exc()函数打印异常堆栈跟踪信息,往往只是用于调试,给程序员提示信息。堆栈跟踪信息对最终用户是没有意义的。捕获到异常之后应该给用户弹出一个对话框,提示用户输入日期无效,请用户重新输入,用户重新输入后再重新调用上述函数。这才是捕获异常之后的正确处理方法。

3、释放资源

有时try-except语句会占用一些资源,如打开文件、网络连接、打开数据库连接和使用数据结果集等,这些资源不能通过Python的垃圾收集器回收,需要程序员释放。为了确保这些资源能够被释放,可以使用finally代码块或with as 自动资源管理。

3.1 finally代码块

try-except语句后面还可以跟有一个finally代码块,try-except-finally语句语法如下:

try:
    <可能会抛出异常的语句>
except [异常类型I]:
    <处理异常>
except [异常类型II]:
    <处理异常>
...
except [异常类型n]:
    <处理异常>
finally:
    <释放资源>

无论是try正常结束还是except异常结束都会执行finally代码块。
如果抛出了异常也会执行finally代码块,可以使用else解决该问题。

3.2 else代码块

与while和for循环类似,try语句也可以带有else代码块,它是在程序正常结束时执行的代码块。

 try:
    <可能会抛出异常的语句>
except [异常类型I]:
    <处理异常>
except [异常类型II]:
    <处理异常>
...
except [异常类型n]:
    <处理异常>
else:
    <执行语句>
finally:
    <释放资源>

3.3 with as 代码块自动资源管理

上述程序虽然"健壮",但程序流程比较复杂,这样的程序代码难以维护。为此Python提供了一个with as代码块帮助自动释放资源,它可以替代finally代码块,优化代码结构,提高程序可读性。with as提供了一个代码块,在as 后面声明一个资源变量,当 with as代码块结束时自动释放资源。

4、自定义异常类

有些公司为了提高代码的可重用性,自己开发了一些Python类库,其中有自己编写的一些异常类。实现自定义异常类需要继承Exception类或其子类。

    # coding utf-8

    class MyException(Exception):
        def __init__(self,message):
            super().__init__(message)

上述代码实现了自定义异常,代码定义了构造方法类,其中的参数message是异常描述信息。super().init(message)是调用父类构造方法,并把参数message传入给父类构造方法。自定义异常就是这样简单,只需要提供一个字符串参数的构造方法就可以了。

5、显示抛出异常

除了系统创建的异常,也可以通过raise语句显示抛出异常,语法格式如下:

    raise BaseException或其子类的实例

显示抛出异常的目的有很多,例如不想某些异常传给上层调用者,可以捕获之后重新显示抛出另外一种异常给调用者。

注意:raise显示抛出的异常与系统生成并抛出的异常在处理方式上没有区别,就是两种方法,要么捕获自己处理,要么抛给上层调用者。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值