执行with obj语句时,他执行方法obj.__enter__()来指示正在进入一个新的上下文,当控制流离开该上下文时,就会执行方法obj.__exit__(exc_type, exc_val, exc_tb)。如果没有引发异常,这三个参数都为None,否则他们将包含导致控制流离开上下文的异常相关的类型,值和跟踪信息。
with open("debuglog","a") as f:
f.write("aaa ")
statements
进入with语句后自动打开文件,离开这个代码块之后,自动关闭文件。
import threading
lock=threading,.Lock()
with lock:
#关键部分
statements
#关键部分结束
在第二个例子中,当控制流进入with语句后面的代码时自动请求一个锁定,而在控制流离开时自动释放这个锁定
#! /usr/bin/python #coding:utf-8 #with语句只对支持上下文管理协议(__enter__() 和__exit__())的对象有效 #用户自定义的类可以实现这些方法,从而定义他们自己的上下文管理 #as var 中的var是说明符,如果指定了该说明符,obj.__enter__()的返回值将保存在var中 class MyWith(object): def __init__(self,thelist): self.thelist=thelist def __enter__(self): self.workingcopy=list(self.thelist) return self.workingcopy def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is None: self.thelist[:]=self.workingcopy return False items=[1,2,3] with MyWith(items) as w: w.append(4) w.append(5) print items #[1, 2, 3, 4, 5] try: with MyWith(items) as w: w.append(6) w.append(7) raise RuntimeError("We're hosed ") #在修改的过程中如果发生异常,那么修改修改就不会生效 except RuntimeError as e: print e print items #[1, 2, 3, 4, 5] "通过包装生成器函数,contextlib模块可以更加容易的实现自定义上下文管理器" from contextlib import contextmanager @contextmanager #装饰器 def Mywith2(thelist): workingcopy=list(thelist) yield workingcopy #仅在没有错误的时候才能修改原列表 thelist[:]=workingcopy """ 在上面这个例子中,把传递给yiled的值用作了__enter__()方法的返回值。调用__exit__()方法时,执行将在yield语句后回复 """ with Mywith2(items) as w: w.append('a') w.append('b') print items