python3:Python 异常处理以

2023-01-31 01:01:01 python 异常 python3

try …except…else 语句

是处理异常公式, try 是有可能抛异常的代码块, except 抓取异常的类型, else 是指当没有抓到抛错,就运行这块代码。请看下下边的例子:

try:
    print("抓取的有可能的代码块")
    raise ioError
except IOError as e:
    print("except  IOError")
except OSError as e:
    print("except OSError")
else:
    print("other erro")

finally:
    print("i am  finally")
#打印结果:
抓取的有可能的代码块
except  IOError
i am  finally

从结果来看 走的路线是:
try(按照raise 的error 找except)>找到except并执行except代码块>执行finally语句块
如果没有抛错走的路线是:
try 没有error>走else 语句>finally
看来不管有没有错误, finally 语句一定会执行到。
在用到finally 要注意他会覆盖 except or else 的返回值。

def try_list():
    try:
        print("抓取的有可能的代码块")

        raise OSError
        return  1

    except IOError as e:
        print("except  IOError")
        return 2
    except OSError as e:
        print("except OSError")
        return 3
    else:
        print("other erro")
        return 4

    finally:
        print("i am  finally")
        return 5

print(try_list())
#打印结果

抓取的有可能的代码块
except  IOError
i am  finally
5

从打印的结果 ,他覆盖了 return 3。
如果走else路线同样return 的4 也会被覆盖, 自己试试下。
那小伙伴有疑问 什么情况下使用 finally 呢
答案: 是在释放资源的时候
看下边的例子。

def try_list():
    try:
        fp=open("Test。txt")
        raise OSError
        fp.close()
    except IOError as e:
        fp.close()
    except OSError as e:
        fp.close()
        print("except OSError")
    else:
        print("other erro")
        fp.close()

大家看了 吗, 只要有流程的分支的地方一定要加上这个 fp.close(),
如果再加分支,还需要再加这个close 函数。
有没有更好的解决方法吗? 答案就是 用finally。请看下边的代码:

def try_list():
    try:
        fp=open("Test。txt")
        raise OSError      
    except IOError as e:      
    except OSError as e:    
        print("except OSError")
    else:
        print("other erro")
    finally:
        fp.close()

大家看看是不是很神奇, 资源的释放不光是文件的关闭,还有socket 连接,数据库的连接

上边的内容只是复习下异常处理的内容, 下边才是重头戏 with上下文管理器

with上下文管理器

with上下文管理器协议包括两个魔法函数 1.__enter__2.exit
用实例来解释下这两个魔法函数

class Person:
    def __enter__(self):    #获取资源
        print("enter")
    def __exit__(self, exc_type, exc_val, exc_tb):   #释放资源
        print("exit")
    def said(self):
        print("said")
        
 with Person() as P:
   P.said()

打印结果是:
enter
Traceback (most recent call last):
exit
File “C:/Users/tengfei/PyCharmProjects/test1/alert.py”, line 12, in
P.said()
AttributeError: ‘NoneType’ object has no attribute ‘said’

根据提示我们就知道了, 我们实例化是“NoneType” 类型,意思就是空的对象。

原因是 因为我们在获取资源(enter)没有返回值,所以默认返回的是空。
我们加上 返回值 就可以运行成功了如下:

class Person:
    def __enter__(self):  #并没有调用,也会运行这个函数
        print("enter")  
       # return  self

    def __exit__(self, exc_type, exc_val, exc_tb):   #并没有调用,也会运行这个函数
        print("exit")
    def said(self):
        print("said")

with Person() as P:
    P.said()

打印结果:
enter #并没有调用,也会运行这个函数
said
exit #并没有调用,也会运行这个函数

总结
上下文管理器协议 是用with 进行调用,默认调用了 enter 和 exit 两个魔法函数。
with是对try…expect…finally语法的一种简化,并且提供了对于异常非常好的处理方式。
根据实际需要应用在不同的场景。

相关文章