上下文管理器与with语句(笔记)

    with语句支持由上下文管理器对象控制的运行时上下文执行一系列语句
    执行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



原文地址:https://www.cnblogs.com/cmustard/p/6769953.html