其实with as 是python的控制流语句,像if ,while等的,只是比那个难理解罢了
首先我先摘抄一段别人的代码大体上给你们理解理解
首先请看下边的解释:
是不是不明白,其实我看了也觉得不明白,很晕,很绕,
下面给大家解释一下,所谓上下文管理协议,其实是指with后面跟的ecception一般是一个类的实体,这个类的实体要包含__enter__和__exit__函数的定义才行
这个类吗 想必大家都知道了,还有try/finally try/except等等这些异常处理方法我就不解释了。我就直奔正题。对于__enter__和__exit__方法这两个方法被称为 魔术方法 。其实是python的内置函数,那么这两个方法到底是怎么用的那,我们来看一个例子
class Closer:
def __init(self,obj):
self.obj = obj
def __enter__(self):
return self.obj
def __exit__(sekf,exception_type,exception_val,trace)
try:
self.obj.close()
except AttributeError:
print "NOt closable"
return True
这是才定义一个叫做Closer的类,我们看一下这个类中有什么
1. 一个__init__方法,__init__方法是个魔术方法,就是内置方法,在类初始化对象的时候被执行,起到初始化的作用
2. 一个__enter__方法,专门用于with 的一个内置方法,他的返回值要跟with as 语句中跟在as 后边的variable.
3. 一个__exit__方法,用于with 语句的一个内置方法当with as语句中的with-block被执行或者终止后,这个类的对象应该做什么,如果这个代码执行成功,则exception_type, exception_val。trace输入值都是空,如果代码出错了,就会变成像try/exception/finally语句一样
with exception as varable
with-block
它的执行过程是:
首先执行exception 里面的__enter__函数,它的返回值会赋给as 后边的variable。像让他返回什么就返回什么,只要你知道怎么处理就行了,如颗不写 as variable ,返回值就会被忽略。然后,开始执行with-block中的语句,不论成功失败(比如发生异常,错误,设置sys.exit()),在with-block执行完成后,会执行expection中的__exit__函数
然后可能有的同学会问,这又跟try/finally有什么关系呢,其实这样的过程等价与
try:
执行__enter__的内容
执行 with_block
finally:
执行__exit__内容
这就应该懂了吧 然后我们这时候再使用网上那些说的很迷的例子看一看 你就会明白了
class Sample(object): # object类是所有类最终都会继承的类
def __enter__(self): # 类中函数第一个参数始终是self,表示创建的实例本身
print("In __enter__()")
return "Foo"
def __exit__(self, type, value, trace):
print("In __exit__()")
def get_sample():
return Sample()
with get_sample() as sample:
print("sample:", sample)
然后我们看一下结果是不是和你想的是一样的
In __enter__()
sample: Foo
In __exit__()
我们然后来分析一下程序是怎么运行的
- 首先我们调用get_sample()函数,返回Sample类
- 执行Sample类中的__enter__()方法,打印"in__enter()"字符串,并将字符串“Foo”赋值给 as 后边的sample变量;
- 执行with__block代码块,即打印"sample: %s"字符串,结果为“sample Foo”
- 执行with__block代码块结束后,返回Sample()类,执行类方法__exit__().因为在执行with__block代码块时并没有错误返回,所以type,value,trace这三个argument都没有值,直接打印print"in__exit__()"