python上下文是什么_python之简述上下文管理

上下文管理器

原理

上下文管理能保证资源会被正确回收,即保证退出步骤的执行。其用处最多的是,作为确保资源被正确回收的一种方式。

一种重复使用的 try-except-finally 结构的有效机制,因为其功能是封闭代码,且可以填充任意格式的代码块。

语法上 __enter__不接受其余参数,除了自带的self之外,__exit__在不包括self参数外,还包括三个参数(一个异常类型,一个异常实例和一个回溯),即exc_type,exc_instance,traceback,默认设置为None

可以通过让一个__exit__方法返回False实现异常传播,或者返回True终止异常。如果抛出另一个异常,将会代码原本的异常被发出去。

编写上下文的场景

资源清理,例如打开数据库,打开文件等需要被正确关闭的资源

避免重复

1.传播异常

2.终止异常

3.处理特定异常类(实例4)

4.不包括的子类(实例5)

原则1:简单的终止所有异常与try-except语句相同,但终止过多的错误会造成代码调试困难,一些隐含错误也会错误,造成过多的不确性。

代码讲解

实例1

# coding: utf-8

class ContextManager(object):

def __init__(self):

self.entered = False

def __enter__(self):

self.entered = True

return self

def __exit__(self, exc_type, exc_val, exc_tb):

self.entered = False

cm = ContextManager() # 实例化一个对象,如果在其余地方不使用实例对象

# 写成 with ContextManager() as cm:

with cm:

print(cm.entered) # enter 方法返回对象,在 enter 作用范围内 self.enter 为 True

print(cm.entered) # 执行了 exit 方法,返回的是 False

实例2

__exit__能处理异常,代码内引起的异常首先传给了__exit__并得到了正常的处理,返回False即异常被重新抛出给主模块,返回True则终止了异常在__exit__方法内

# coding: utf-8

class BubbleExceptions(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_val, exc_tb):

if exc_val:

print("Bubbing up exception: {}".format(exc_val))

return True

with BubbleExceptions():

print(5/0)

"""

__exit__ 返回 False

Bubbing up exception: division by zero

Traceback (most recent call last):

File "/home/yuge/Documents/book/test.py", line 15, in

print(5/0)

ZeroDivisionError: division by zero

__exit__ 返回True

Bubbing up exception: division by zero

"""

实例3: 上下文内被正常处理的异常,不会发给__exit__

# coding: utf-8

class BubbleExceptions(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_val, exc_tb):

if exc_val:

print("Bubbing up exception: {}".format(exc_val))

return False

with BubbleExceptions():

try:

print(5/0)

except ZeroDivisionError:

print("这是一个错误!")

"""

运行结果:

这是一个错误!

"""

实例4:__exit__可以处理特定异常类

即在__exit__方法里封装代码,将处理特定异常类的代码放进去,有点像try-except一样,最多的不同是,其代码可以重用。

# 处理特定的异常,并根据是否提起了其他异常类来决定是否返回 True 或 False

# coding: utf-8

class HandleValueError(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_val, exc_tb):

if not exc_type:

# 即没有异常出现

return True

if issubclass(exc_type, ValueError):

print("捕捉到了一个 ValueError:{}".format(exc_val))

return True

return False

with HandleValueError():

# raise ValueError("错误的值!")

raise TypeError("错误的类型!")

"""

raise ValueError("错误的值!")

捕捉到了一个 ValueError:错误的值!

raise TypeError("错误的类型!")

Traceback (most recent call last):

File "/home/yuge/Documents/book/test.py", line 22, in

raise TypeError("错误的类型!")

TypeError: 错误的类型!

"""

实例5:如何处理特定的类,不处理其子类

# coding: utf-8

class ValueErrorSubclass(ValueError):

pass

class HandleValueError(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_val, exc_tb):

if not exc_type:

return True

# 这里只处理 ValueError 的错误,即不处理基类的子类

if exc_type == ValueError:

print("处理了一个 ValueError 的错误:{}".format(exc_val))

return True

# if issubclass(exc_type, ValueError):

# # 这里处理了包括 基类的 所有类集体

# print("处理了基于 ValueError 的错误:{}".format(exc_val))

# return True

return False

with HandleValueError():

raise ValueErrorSubclass("这就是个失误")

"""

包括 issubclass

处理了基于 ValueError 的错误:这就是个失误

注释了 issubclass 之后

Traceback (most recent call last):

File "/home/yuge/Documents/book/test.py", line 30, in

raise ValueErrorSubclass("这就是个失误")

__main__.ValueErrorSubclass: 这就是个失误

"""

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值