上下文管理协议

上下文管理协议,即with语句。为了让一个对象兼容with语句,必须要在这个对象的类中声明__enter__和__exit__方法

class Open():
    def __init__(self,name):
        self.name=name

    def __enter__(self):
        print('执行enter')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('执行exit')

#with触发__enter__,返回值赋值给f,执行完with语句后触发__exit__
with Open('a.txt') as  f:
    print(f)

print('123')

#result:
# 执行enter
# <__main__.Open object at 0x005FF950>
# 执行exit
# 123
View Code

1.with obj-------->触发obj.__enter__(),拿到返回值

2.as f---------->f=返回值

 

3.执行代码块;

一、没有异常:整个代码块运行完毕后触发__exit__,它的三个参数都为None

二、有异常:从异常出现的位置直接触发__exit__

  a.如果__exit__的返回值为True,代表吞掉了异常

  b.如果__exit__的返回值不为True,代表吐出了异常,后面的代码都不会运行

  c.__exit__的运行完毕就代表了整个with语句的执行完毕

class Open():
    def __init__(self,name):
        self.name=name

    def __enter__(self):
        print('执行enter')
        return self
    #当with语句异常时,才会有报错信息,参数才有值
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('执行exit')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return True
#-----------------------------------------
# #with触发__enter__,返回值赋值给f,执行完with语句后触发__exit__
# with Open('a.txt') as  f:
#     print(f)
#
# #result:
# # 执行enter
# # <__main__.Open object at 0x0066FFB0>
# # 执行exit
# # None
# # None
# # None
#
#---------------------------------------------
#执行完__exit__,不会继续向下执行
with Open('a.txt') as  f:
    print(f)
    print(asdfsdgd)
    print(f.name)
#
# #result:
# # 执行enter
# # Traceback (most recent call last):
# # <__main__.Open object at 0x00BFFFB0>
# #   File "D:/Programs/Python/Python37-32/untitled1/day21/time.py", line 29, in <module>
# # 执行exit
# # <class 'NameError'>                   #exc_type
# # name 'asdfsdgd' is not defined        #exc_val
# # <traceback object at 0x00CA56C0>      #exc_tb
# #     print(asdfsdgd)
# # NameError: name 'asdfsdgd' is not defined

#-------------------------------------------------------------
#在__exit__加上return True:把异常吞了  , 跳出with语句,继续向下执行

#result:
# 执行enter
# <__main__.Open object at 0x00D0FFB0>
# 执行exit
# <class 'NameError'>
# name 'asdfsdgd' is not defined
# <traceback object at 0x00DA6698>
View Code

 

posted @ 2019-03-31 13:09  wind_y  阅读(222)  评论(0编辑  收藏  举报