26_python笔记-上下文管理器


个人博客
https://blog.csdn.net/cPen_web

#01 上下文管理器的语法

#注:enter方法可以写连接数据库的操作,exit方法写断开连接的操作,用with去管理
#注:with打开的文件对象,就是1个上下文管理器
#注:with语句可以去管理 上下文管理器对象
#注:使用with管理,上下文管理器 不需要自己调用 _enter _、_exit _方法
示例:上下文管理器

#上下文管理器 基本语法

# 1、普通方法打开文件对象
fp = open("test.txt","a+")  # a+ 追加写
print(dir(fp))
#结果为 [ …'__enter__', …, '__exit__'…]
#注:有__enter__、__exit__方法,是上下文管理器
fp.write("this is test")
fp.close()  #注:处理结束后,把它关掉,不然占资源

# 2、用with语句执行
with open("test.txt","a+") as f:    #注:赋给f对象
    f.write("write test")
    #退出语句执行之后 with自动回收对象
    #因为打开的文件对象是上下文管理器
    #注:open("test.txt","a+"):上下文表达式

with open("test.txt","a+"):
    print("this is test")
    #注:不需要上下文管理器对象,可以这样写,没有意义

#迭代器 有 __next__,__iter__方法

#上下文管理器
class ContextManger():	#注:定义1个上下文管理器的对象
    def __init__(self):
        self.entered = False

    def __enter__(self):
        print("__enter__ called")
        self.entered = True
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
    #注:exc_type, exc_val, exc_tb 异常类型、异常值、异常嘻嘻
    #注:这3个参数不需要自己传,with语句会帮忙管理。这3个参数接收异常信息
        print("__exit__ called")
        print(exc_type, exc_val, exc_tb)
        self.entered = False

cm01 = ContextManger()  #注:创建实例对象
print(cm01.entered)

# with ContextManger() as cm02:	#注:可以这样管理
with cm01:				#注:也可以这么写
    print(cm01.entered)
    print("this is test")
#结果为
# False
# __enter__ called
# True
# this is test
# __exit__ called
# None None None    #注:没有异常就是None,不会报错

#with语句会先执行__enter__方法,退出的时候自动执行__exit__方法
#正常退出的话,__exit__接受的三个参数都是None
#注:不改变代码本身的工作,但又添加额外的功能
#注:上下文管理器 一般来说用作于清理资源、清理连接
# with语句执行的解析
# ·当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法
#       ·__exit__()方法有3个参数
#       ·如果with语句正常结束,三个参数全部都是 None

#02 上下文管理器异常处理

示例:_exit _

#__exit__ 接受三个参数  异常类,异常值,回溯信息

#上下文管理器  传播异常  终止异常

class MyException():
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_val: #注:如果有异常发生
            print(f"My exception: {exc_val}")
        # return False   #注:传播异常,给解释器识别
        return True     #注:终止异常

with MyException():#使用上下文管理器
    print(1+1)  #注:没有异常,输出为2
with MyException():
    print(1/0)  #注:False时 有异常
#False时 结果为 My exception: division by zero
#True时 结果为
# My exception: division by zero	#注:True时  不报错,程序不中断
#注:True时 把异常传递出去,给解释器知道

print("end......")
#注:return False 不会执行 end......
#注:return True  执行了   end......

#注:return True时,有点类似于异常捕获机制 try...except...
#注:这个更NB,捕获所有异常

#return True
#try:
#    do_sth
#except:
#    do_sth

示例:如果是ValueError异常,终止异常;如果不是,传播异常

class MyException():
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        if issubclass(exc_type, ValueError): #注:如果是ValueError异常及子类异常
        # if exc_type == ValueError:  #注:exc_type是类,所以判断条件ValueError类
            return True #终止异常
        return False    #传播异常

with MyException():
    print(1+1)
    raise ValueError("test value error")

#注:issubclass(exc_type, ValueError) 如果是ValueError异常及子类异常

#03 contextlib模块

示例:contextlib实现上下文管理器

# contextlib实现上下文管理器
#不需要手写class 实现上下文管理器
#使用contextlib模块

import contextlib

@contextlib.contextmanager
def mycontext():
    print("enter context")
    yield   #注:生成器函数
    print("exit context")

c1 = mycontext()
print(dir(c1))
#结果为 […'__enter__',  '__exit__'…]
#注:使用装饰器后 就是上下文管理器了。不使用装饰器,只是生成器对象

with c1:
    print("xxxxxxxxxx")
#结果为
# enter context
# xxxxxxxxxx
# exit context
#注:yield之前是它的__enter__方法,yield之后是它的__exit__方法
#注:这个方法不能终止异常,只能用try...except...进行异常捕获
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mycpen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值