使用实例:
with open('./data.txt') as file:
file.read()
基本思想:with所求值的对象必须有__enter__方法和__exit__方法
基本流程:with后面的语句被求值后,enter方法被调用,返回一个对象赋予as后的变量,with模块中所有的语句被执行完毕后,调用前面返回对象的exit方法
In [4]: class Sample:
...: def __enter__(self):
...: print('enter')
...: return "对象"
...: def __exit__(self,type,value,trace):
...: print('exit')
In [5]: def get_Sample():
...: return Sample()
...:
In [6]: with get_Sample() as sample:
...: print('sample',sample)
enter
sample 对象
exit
完整功能实例(报异常):可以在exit()中输出异常
In [9]: class Sample:
...: def __enter__(self):
...: return self
...: def __exit__(self,type,value,trace):
...: print('type:',type)
...: print('value',value)
...: print('trace',trace)
...: def do_Something(self):
...: bar = 1/0
...: return bar+10
...:
In [10]: with Sample() as sample:
...: sample.do_Something()
...:
type: <class 'ZeroDivisionError'>
value division by zero
trace <traceback object at 0x000002777858E748>
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-10-5e52b3552bb5> in <module>
1 with Sample() as sample:
----> 2 sample.do_Something()
3
<ipython-input-9-3ea07c9cf578> in do_Something(self)
7 print('trace',trace)
8 def do_Something(self):
----> 9 bar = 1/0
10 return bar+10
11
ZeroDivisionError: division by zero
创建新的上下文使用实例:
In [21]: import time
In [22]: from contextlib import contextmanager
In [23]: @contextmanager
...: def timethis(label):
...: start = time.time()
...: try:
...: yield #yield之前的语句作为enter函数中的内容,yield之后的语句作为exit函数中的内容,如果有异常,则在yield处返回
...: finally: # 如果有enter函数中有报错,下面的部分不执行
...: end =time.time()
...: print('{}:{}'.format(label,end-start))
...:
In [24]: with timethis('counting'):
...: n = 100000
...: while n>0:
...: n-=1
...:
counting:0.015624046325683594