with语句支持由上下文管理器对象控制的运行时上下文执行一系列语句
执行with obj语句时,他执行方法obj.__enter__()来指示正在进入一个新的上下文,当控制流离开该上下文时,就会执行方法obj.__exit__(exc_type, exc_val, exc_tb)。如果没有引发异常,这三个参数都为None,否则他们将包含导致控制流离开上下文的异常相关的类型,值和跟踪信息。
with open("debuglog","a") as f:
f.write("aaa\n")
statements
进入with语句后自动打开文件,离开这个代码块之后,自动关闭文件。
import threading
lock=threading,.Lock()
with lock:
#关键部分
statements
#关键部分结束
在第二个例子中,当控制流进入with语句后面的代码时自动请求一个锁定,而在控制流离开时自动释放这个锁定
执行with obj语句时,他执行方法obj.__enter__()来指示正在进入一个新的上下文,当控制流离开该上下文时,就会执行方法obj.__exit__(exc_type, exc_val, exc_tb)。如果没有引发异常,这三个参数都为None,否则他们将包含导致控制流离开上下文的异常相关的类型,值和跟踪信息。
with open("debuglog","a") as f:
f.write("aaa\n")
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