#案例一安全
class Foo(object): def __init__(self): print('实例化一个对象') def __enter__(self): print('进入') def __exit__(self, exc_type, exc_val, exc_tb): print('退出') obj = Foo() with obj: print('正在执行') #上面代码执行结果为: 实例化一个对象 进入 正在执行 退出 #结论 咱们知道,实例化Foo,获得obj对象,会执行Foo的__init__方法,也就是打印了第一句; 按照,程序从上至下执行,应该会打印“正在执行”才对,为何会在它以前先打印了进入,在它以后打印了退出呢? 由于咱们在定义Foo时,定义了__enter__和__exit__方法,那么咱们实例化的对象obj就是一个上下文管理器, 即含有__enter__和__exit__方法的对象就是上下文管理器。 with 上下文管理器: 语句体 当with遇到上下文管理器,就会在执行语句体以前,先执行上下文管理器的__enter__方法,而后再执行语句体,执行完语句体后,最后执行__exit__方法 这也就是为何会出现文章开头的状况的缘由。
##案例二编码
class Foo(object): def __init__(self): print('实例化一个对象') def __enter__(self): print('进入') def __exit__(self, exc_type, exc_val, exc_tb): print('退出') # return True obj = Foo() with obj: raise ImportError print('正在执行')
#结果以下spa
#把上面代码中咱们注释掉的那一行代码取消注释,结果以下code
咱们会发现,虽然咱们故意在语句体中抛出一个错误,按照正常状况,执行到报错地方就不会执行了,而__exit__是在语句体执行完以后执行的,但仍是执行了__exit__方法;当咱们在__exit__中给一个返回值为Ture时,就会忽略错误。对象
#结论blog
#结论 全部咱们能够发现 with语句相似 try : except: finally: 的功能:可是with语句更简洁。并且更安全。代码量更少。 出现异常时,若是 __exit__ 返回 False(默认不写返回值时,即为False),则会从新抛出异常,让with 以外的语句逻辑来处理异常,这也是通用作法;若是返回 True,则忽略异常,再也不对异常进行处理
##案例三ci
class Foo(object): def __init__(self): print('实例化一个对象') def __enter__(self): print('进入') # return self def __exit__(self, exc_type, exc_val, exc_tb): print('退出') with Foo() as obj: print(obj,type(obj)) print('正在执行')
#结果get
#把上面代码中咱们注释掉的那一行代码取消注释,结果以下it
#结论io
调用上下文管理器的 __enter__ 方法时;若是使用了 as 子句,则将 __enter__() 方法的返回值赋值给 as 子句中的目标 with 上下文管理器 as target: 代码语句体 with后面必须跟一个上下文管理器,若是使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 能够是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
##案例四
咱们常常会看到这样的代码: with open("/tmp/foo.txt") as file: data = file.read()
#结论
这里使用了 with 语句,无论在处理文件过程当中是否发生异常,都能保证 with 语句执行完毕后已经关闭了打开的文件句柄。若是使用传统的 try/finally 范式,则要使用相似以下代码: somefile = open(r'somefileName') try: for line in somefile: print line # ...more code finally: somefile.close() 比较起来,使用 with 语句能够减小编码量。已经加入对上下文管理协议支持的还有模块 threading、decimal 等。
#补充
with只能配合上下文管理器使用,常见的上下文管理器有:
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore