[关闭]
@tingyuge 2016-10-01T14:47:01.000000Z 字数 1304 阅读 1672

Python的with理解

Python


with做为一种上下文管理器,在Python中的作用可以简单的理解为是用来代替try...except...finally的处理流程。

with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。对于一些需要预先设置,事后要清理的一些任务,with提供了一种非常方便的表达。在紧跟with后面的语句被求值运算后,会调用运算返回对象的__enter__方法,并将__enter__的返回结果赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用返回对象的__exit__()方法执行清理工作。

就像在文件操作中:

  1. file = open("file.txt")
  2. try:
  3. data = file.read()
  4. finally:
  5. file.close()

在使用了with...as...后,代码将精简为:

  1. with open("file.txt") as file:
  2. data = file.read()

在上面的代码中,open()函数会返回一个类型为file的对象,该对象具有__enter____exit__方法(可以通过dir(file),type(file)查看),之后调用对象的__enter__方法,将返回值赋值给file变量,所以在使用with...as...操作文件时不需要显示的关闭文件。

既然知道with...as...中最重要的就是__enter__exit__,那我们就可以来自定义一个上下文管理器。

其中:
__enter__方法将在进入代码块前被调用。
__exit__将在离开代码块之后被调用(即使在代码块中遇到了异常)。
  1. class WithDemo:
  2. def __enter__(self):
  3. print "in __enter__"
  4. return "WithDemo"
  5. def __exit__(self, type, value, trace):
  6. print "in __exit__"
  7. def get_demo_with():
  8. return WithDemo()
  9. with get_demo_with() as demo:
  10. print "demo:", demo

执行结果为:

  1. in __enter__
  2. demo:WithDemo
  3. in __exit__

在刚开始的时候就已经说,with..as..可以用来代替try...except...finally...的流程操作,上面都在说try...finally...的情况,那异常呢?如果仔细点会发现__exit__()的参数有三个,这三个参数便是为异常提供处理的参数。

  1. class WithDemo:
  2. def __enter__(self):
  3. return self
  4. def __exit__(self, type, value, trace):
  5. print "type:", type
  6. print "value:", value
  7. print "trace:", trace
  8. def create_trace(self):
  9. return (1/10) + 10
  10. with WithDemo() as demo:
  11. demo.create_trace()

跑一下代码就能发现代码打印出了type, value, trace。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注