python-异常处理2

1.如何解决异常?

        系统一开始已经内置了一些特定的应用场景;当我们写代码过程中,一旦触发了这个场景,系统内部就会自动的向外界抛出这个问题,也就是我们所谓的异常。程序被终止执行,软件崩溃。

        预防:添加容错代码。

                    弊端:容错代码不属于我们主要的业务逻辑,如果容错代码过过多,会造成代码混乱,主业务不清晰。

        解决:捕捉处理异常

        方案1:

        语法:

        try:

            可能出现异常的代码->(这里不管以后会抛出多少个异常,只会从上往下检测,检测到最后一个,就立即往下去匹配,不会多次检测。)

        except  你要捕捉的异常类别 as(python2使用,)接收异常的形参。->(这一大块可以有多个重复,用于捕捉可能的其他异

                      对于这个异常的处理。                                                                           常,如果针对多个不同的异常有相同的处理方式,那                                                                                                                                         么可以将多个异常合并)

        else 

                      没有出现异常时做的处理。->(这一块必须放在except结束之后(可以省略))

        finally:

                      不管有没有异常,都会执行的代码。->(这一块必须放在最后(可以省略))

        注意:try语句没有捕获到异常,先执行try代码段后,在执行else,最后执行finally。如果捕获异常,首先执行except处理错误,然后执行finally。如果异常名称不确定,而又想捕捉,可以直接写Exception。

try:
    1 / 0
except ZeroDivisionError as ze:
    print("xxxx", ze)
except NameError as ne:
    print("名称错误", ne)
else:
    print(123)
finally:
    print("最后行的内容,不管是否出现异常,都会执行的语句。")
# 异常的合并,针对不同的异常又想合并处理
try:
    1 / 0
    print(name)
# 将异常合并包装成一个元组
except (ZeroDivisionError, NameError) as e:
    print("xxxx", e)
else:
    print(123)
finally:
    print("最后行的内容,不管是否出现异常,都会执行的语句。")
# 当不知道准确的异常时,可以直接使用Exception
try:
    1 / 0
    print(name)
# 将异常合并包装成一个元组
except Exception as e:
    print("xxxx", e)
else:
    print(123)
finally:
    print("最后行的内容,不管是否出现异常,都会执行的语句。")

        方案2:

        作用:适用于执行某一段代码A之前,进行预处理,执行代码A结束后,执行清理操作。不管出现了什么异常,最终都要执行一些清理操作。

        语法:

        with context_expression [as target(s)]

               with-body

        语法图解:

        示例:

        文件读取操作正常步骤:打开文件:f = open("xxx.txt")

                                                    读取文件:f.readlines() -> 如果这一行代码抛出异常,就会影响后续“文件关闭”操作的执行。

                                                    关闭文件:f.close()

        于是,我们想保证,不管读取文件操作有没有异常,都要关闭文件。(try:

                                                                                                                                         打开文件

                                                                                                                                         读取文件

                                                                                                                                    finally:

                                                                                                                                         关闭文件

                                                                                                                                 )

        但是以上写法过于繁琐,于是有了这个方案。

                                                                                                                                 (with open(file) as f:

                                                                                                                                         读取文件

                                                                                                                                 )

        上述代码的问题:代码如果出现异常,并没有处理掉。

try:
    f = open("xxx.jpg", "r")
    f.readlines()
except Exception as e:
    print(e)
finally:
    print("xxxxxx")
    f.close()

# with open("xxx.jpg", "r") as f:
#     f.readlines()

        补充:

        自定义上下文管理器:

        exc_typ:异常的类型, exc_val:异常的值 exc_tb:异常的追踪信息

class Test:
    def __enter__(self):
        print("enter")
        return self
# exc_typ:异常的类型, exc_val:异常的值 exc_tb:异常的追踪信息
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(self, exc_type, exc_val, exc_tb)
        # 手动的追踪出错的位置
        import traceback
        print(traceback.extract_tb(exc_tb))
        print("exit")
        # 当这里返回True的时候,这些异常会自动的传递给退出方法。内部消化,不会再往外传了。如果返回False或者none,则外面
        # 依然会接收到异常。造成代码崩溃
        return True
with Test() as x:
    # print("body", x)
    1 / 0

        contextlib模块:

        @contextlib.contextmanager -> 使用装饰器,让一个生成器编程一个“上下文管理器”

@contextlib.contextmanager
def ze():
    try:
        yield
    except Exception as g:
        print("Error", g)

x = 1
y = 0
with ze():
    x / y

a = 1
b = 0
with ze():
    a / b
    
# try:
#     a / b
# except Exception as f:
#     print("error", f)


# with test() as x:
#     print(3, x)

        contextlib.closing:这个函数让一个拥有close方法,但是不是上下文管理器的对象,变成“上下文管理器”

import contextlib

class Test:
    def t(self):
        print("tttttt")

    def close(self):
        print("资源释放")

    # def __enter__(self):
    #     return self
    # def __exit__(self, exc_type, exc_val, exc_tb):
    #     self.close()

with contextlib.closing(Test()) as t_obj:
    t_obj.t()

        contextlib.nested:python2.7之前,完成多个上下文管理器的嵌套。

# 多上下文管理器嵌套
# with open("xxx.jpg", "rb") as from_file:
#     with open("xxx2.jpg", "wb") as to_file:
#         from_context = from_file.read()
#         to_file.write(from_context)

# python3.x版本后写法
# with open("xxx.jpg", "rb") as from_file, open("xxx2.jpg", "wb") as to_file:
#     from_context = from_file.read()
#     to_file.write(from_context)

# python2.x版本后写法
import contextlib
with contextlib.nested(open("xxx.jpg", "rb"), open("xxx2.jpg", "wb")) as (from_file, to_file):
    from_context = from_file.read()
    to_file.write(from_context)

 

基本小案例:

import contextlib
# 通过导入contextlib,利用contextlib.contextmanager生成一个上下文管理器。yield上面是__enter__。yield下面是__exit__。
@contextlib.contextmanager
def test():
    print(1)
    # yield 后面直接写值,就是下面x的值。
    yield "xxx"
    print(2)

with test() as x:
    print(3, x)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值