上下文管理器实现需要有__enter__()和__exit__()的特殊方法
enter(self): 进入上下文管理器时调用此方法,其返回值将被放入with-as语句中as说明符指定的变量中。
exit(self,type,value,tb):离开上下文管理器调用此方法。如果有异常出现,type、value、tb分别为异常的类型、值和追踪信息。如果没有异常,3个参数均设为None。此方法返回值为True或者False,分别指示被引发的异常得到了还是没有得到处理。如果返回False,引发的异常会被传递出上下文。
对于系统资源,如文件、套接字、数据库连接等,应用程序打开这些文件并执行相应的操作之后,必须关闭。否则消耗资源会导致程序崩溃。
实现方式一:
class File(object):
def __init__(self,filename,mode):
self.filename = filename
self.mode = mode
def __enter__(self):
print("--enter--")
self.f = open(self.filename,self.mode)
return self.f
def __exit__(self, *args):
print("--exit---")
self.f.close()
with File("out.txt","w") as f:
f.write("hello world")
输出结果:
–enter–
–exit—
实现方式二 yield方法
from contextlib import contextmanger
@contextmanger
def File(path,mode):
f = open(path,mode)
yield f
f.close()
with File("out.txt","w") as f:
f.write("hello world hahah")
实例:计算函数运行的时间,使用上下文管理器实现。
import time
class PrintTime(object):
def __enter__(self):
self.t0 = time.time()
def __exit__(self, *args):
print("[time:{time:.2f}s]".format(time = time.time()-self.t0))
def func(number):
li = [1, 2, 4]
if number < 4:
return li[number - 1]
else:
if number > 3:
return func(number - 1) + func(number - 2) + func(number - 3)
if __name__ == "__main__" :
with PrintTime() as t:
func(4)
time.sleep(1)
print("do things")
输出结果:
do things
[time:1.00s]