python中上下文管理器contextmanager

本文深入探讨了Python中上下文管理器的概念,解释了如何通过实现__enter__和__exit__方法创建上下文管理器,以及如何使用@contextmanager装饰器简化这一过程。通过实例演示了with语句如何自动调用这些方法,确保资源的正确管理和异常处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

个人总结:
1、一个类只要实现了__enter__()方法和__exit__()方法,那么这样的类就称为上下文管理器。
就像一个类中实现了__iter__()方法和__next__()方法那么这个类就是一个迭代器,道理类似。
同理生成器是一种特殊的迭代器,特殊就在它里面有yeild,一个函数里面有yield那么它就是个迭代器对象了,而一个函数用@contextmanager装饰器装饰后并且其内部有yield它就是一个上下文管理器对象了。yield之前的代码相当于enter方法,yield之后的代码相当于exit函数,yield后的返回值相当于enter的返回值。

2、with:后面如果是个上下文管理器对象,那就会自动调用其中的enter方法,如果enter方法有返回值则用as xx:的方式接收, xx指向该返回值,没有返回值或不需要接收可以不写 as xx:。当whit:后面的缩进代码块执行结束后则会自动调用其中的exit方法,不管缩进块中的代码有没有产生异常。

举个demo:

 #!/usr/bin/python3
  2 # -*- coding:utf-8 -*-
  3 
  4 # context_manager.py
  5 import time
  6 from contextlib import contextmanager
  7 
  8 
  9 class MyClass():
 10     """一个类只要实现了__enter__方法和__exit__方法,这样的类就称为上下文管理
    器"""
 11 
 12     def __init__(self,file_name,mode):
 13         self.file_name = file_name
 14         self.mode = mode
 15 
 16     def __enter__(self):
 17         print("enter method is running")
 18         self.file = open(self.file_name,self.mode)
 19         return self.file
 20 
 21     def __exit__(self,*args,**kwargs):  # exit 方法有四个参数,具体没研究过
 22         print("exit  method is running")
 23         self.file.write("999999999999")
 24         self.file.close()
 25         #self.f.write("111111111111")  # 整上这个会报错,I/O operation on
                                           # closed file
 26 
 27 
 28 @contextmanager
 29 def my_cm(file_name,mode):
 30     f = open(file_name,mode)
 31     yield f
 32     f.close()
 33     print("f was closed")
 34 
 35 
 36 if __name__ == "__main__":
 37     # 方式一、MyClass类中的enter方法返回值file用as f方式给到f,不接收返回可不
    写
 38     # 1.with后面的对象如果是个上下文管理器就会自动调用其中的enter方法
 39     # 2.with:缩进代码块执行完后会自动调用exit方法,不管缩进代码有没有产生异常
 40 
 41     #a.用as f接收enter的返回值
 42     #with MyClass("test.txt","a") as f:
 43         #f.write("hahhhha")
 45     #b.不需要接收返回值
 46     with MyClass("test1.txt","a"):
 47         for i in range(5):
 48             print(i)
 49             time.sleep(2)
 50 
 51     print("方式一运行结束!")
 52 
 53 
 55     # 方式二、通过装饰器的方式来实现
 56     with my_cm("test3.txt","a") as f:
 57         f.write("您好!有意思")
 58     print("方式二运行结束!")

运行结果:

enter method is running
0
1
2
3
4
exit  method is running
方式一运行结束!
f was closed
方式二运行结束!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值