上下文管理协议

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")
对于一个有思想的人来说,没有地方是荒凉而遥远的
原文地址:https://www.cnblogs.com/quanag/p/10659349.html