python with上下文管理基本使用

with/as的设计是作为常见的try/finally用法模式的替代方案。类似于try/finally语句,with/as语句也是用于定义必须执行的终止或"清理"行为。

主要用在自动关闭文件,对锁的自动上锁和开锁,也可以用类编写自己的上下文管理器

基本格式为

with expression [ as variable]:
  with-block

在这里的expression要返回一个对象,如果as子句存在时,则会把对象赋值给变量variable

lock = threading.Lock()
with lock:
  time.sleep(1)

上下文管理机机制保证锁会在代码块执行前获得,并且代码块执行完就释放,不管有没有发生异常

上下文管理协议

自己实现一个上下文管理协议

1、必须有__enter__和__exit__方法
2、上下文管理器的__enter__方法会被调用,如果as子句存在,其返回值会赋值给as子句中的变量,否则就会丢弃返回值
3、如果with代码块引发异常或者执行完成,__exit__方法就会被调用

#!/usr/bin/env python
class TraceBlock:
	def message(self, arg):
		print("running", arg)
	def __enter__(self):
		print("start with block")
		return self
	def __exit__(self, exc_type, exc_value, exc_tb):
		if exc_type is None:
			print("exit ok
")
		else:
			print("raise an exception", exc_type)
			print("instance", exc_value)
			return False

with TraceBlock() as action:
	action.message("hello")

with TraceBlock() as action1:
	action1.message("xxxxx")
	raise TypeError
	print("unreache")



tutu@linux-xk1e:~/Documents> ./with1.py
start with block
running hello
exit ok

start with block
running xxxxx
raise an exception <class 'TypeError'>
instance
Traceback (most recent call last):
  File "./with1.py", line 21, in <module>
    raise TypeError
TypeError

使用contextlib模块

contextlib中的@contextmanager装饰器能减少创建上下文管理器的代码量,不用写一个完整的类,定义enter和exit方法, 只需要实现一个yield的生成器,返回__enter__需要的值

在contextmanager装饰的生成器中,yield的作用是把函数体分成两部分,yield前面的代码在with块开始时(即调用__enter__方法)执行,yield语句后面的代码在with结束时(即调用_exit_)执行

#!/usr/bin/env python
import contextlib

@contextlib.contextmanager
def TraceBlock():
	print("befgin")
	yield "ABCDEFG"
	print("end")

# yield返回的ABCDEFG会赋给var变量
with TraceBlock() as var:
	print(var)


原文地址:https://www.cnblogs.com/baitutu/p/7565123.html