上下文管理协议
class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__") with Open('a.txt') as f: # with Open会触发__enter__, __enter__返回的值会赋值给f ,然后会执行with里面的代码块,最后会执行__exit__ print(f) print(f.filename) print("============>") print("============>") print("============>") print("============>") print('111111111111111111111')
返回结果:
__enter__ # with Open触发__enter__的执行,把返回值给了f
<__main__.Open object at 0x0000000000B9DC18> # 打印了f的内存地址
a.txt # 打印了f.filename
============> # 打印了4个print
============>
============>
============>
__exit__ # with里面执行完毕会触发__exit__的执行
111111111111111111111 # 最后会执行print('111111111111111111111')
来我们看下另外一种情况:
class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__")print(exc_type) print(exc_val) print(exc_tb)
with Open('a.txt') as f: print(f.filename) print(dkasfklafl) print("============>") print("============>") print("00000000")
执行结果:
Traceback (most recent call last): File "E:/seafile backup/python3/python3 project/day 28/s1 上下文管理协议.py", line 43, in <module> print(dkasfklafl) NameError: name 'dkasfklafl' is not defined __enter__ # with Open会触发__enter__,把返回值赋值给f a.txt # 打印f.filename __exit__ # 打印print(dkasfklafl),因为没有这个变量,报错,直接触发__exit__ <class 'NameError'> # 打印一个错误类 name 'dkasfklafl' is not defined # 提示变量名没有定义 <traceback object at 0x0000000000B89748> # 追踪信息 注意:报错之后,下面的代码都不会运行了
# 比如:print("============>") print("============>") print("00000000")都没有运行
会报错,现在我们解决刚刚的报错
class Open: def __init__(self,filename): self.filename = filename def __enter__(self): print("__enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): print("__exit__") print(exc_type) print(exc_val) print(exc_tb)return True
with Open('a.txt') as f: print(f) print(dkasfklafl) print("============>") print("============>") print("00000000")
执行结果
__enter__ # with Open触发__enter__, __enter__返回值赋值给f <__main__.Open object at 0x000000000105DD68> # 执行print(f) __exit__ # 碰到print(dkasfklafl)异常,触发__exit__ <class 'NameError'> # print(exc_type) 打印错误类型 name 'dkasfklafl' is not defined # print(exc_val) ,打印提示信息,提示变量名没有定义 <traceback object at 0x0000000001069748> # print(exc_tb) ,打印追踪信息 ,之后就跳出with的代码块,执行下面的代码 00000000 # 执行print("00000000")
对于一个有思想的人来说,没有地方是荒凉而遥远的