Python 高级编程和异步IO并发编程 --04_11 Python中的上下文管理器with语句

强颜欢笑 提交于 2020-03-17 12:00:06

# try_except_finally
try:
    f_read = open("Tom.txt")
    print("code started")
    raise KeyError
    f_read.close()
    #raise IndexError  # 此时就没有捕获到异常,代码出错
    f_read.close()  # 打开正常时,才会执行该语句,如果有抛出异常,则不会执行该语句,
                    # 此时应该在每次抛出error时,都执行f_read.close(),这样才可以释放该文件

except KeyError as e:
    print("key error")
    f_read.close()
else:
    print("other error")  # 在没有抛异常时,捕捉其它异常。
finally:   # 无论前面的代码是否允许,都会执行finally后面的语句
    print("finally")
    f_read.close()   # finally语句一般用于资源释放

# try_except_finally
def exe_try():
    try:
        print("code started")
        raise KeyError
        return 1        # 前一句,raise了一个KeyError,导致该语句没被执行

    except KeyError as e:
        print("key error")
        return 2        # 此时return 2,为什么执行结果会return 4?
                        # 如果finally里面有return语句,就会return finally里面的return语句
                        # 如果finally里面没有return语句,就会return调用之时的return语句 return 2
                        # return 2时,将2压入堆栈里面,继续执行finally,在finally里面如果发现return语句,
                        # 则将4压入栈顶。如果finally里面return语句,则返回之前压入的2
    else:
        print("other error")  # 在没有抛异常时,捕捉其它异常。
        return 3

    finally:   # 无论前面的代码是否允许,都会执行finally后面的语句
        print("finally")
        #return 4

if __name__ == "__main__":
    result = exe_try()
    print(result)
# 上下文管理器 with语句
class Sample():
    def __enter__(self):    # with 语句,默认会首先调用__enter__
        print("enter") 
        # 获取资源
        return self
    def __exit__(selfs,exc_type,exc_val,exc_tb):    # with 语句,来开时,会默认调用__exit__方法
        # 释放资源
        print("exit")
    def do_something(self):
        print("doing something")

with Sample() as sample:    # with语句可以实例化一个对象/类;嵌入with语句后,就会自动调用__exit__
    sample.do_something()   # 我们并没有调用__enter__/__exit__这个魔法函数,但是系统还是自动的调用到__enter__/__exit__
# 我们在定义类时,只需要在__enter__语句获取资源,__exit__语句释放资源,
# 使用with语句,python解释器就可以对它们进行默认使用,此即上下文管理器协议
C:\Users\Amber\PycharmProjects\test0\venv\Scripts\python.exe C:/Users/Amber/PycharmProjects/test0/Chapter03/with_test.py
enter
doing something
exit

__enter__  + __exit__ 就构成了python上下文管理器协议,后续中应该常用这种架构

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!