上下文管理协议

一.使用场景
我们经常在进行文件操作时使用with语句来进行操作,这就关系到了上下文管理协议了。
二.使用
在使用with语句时,我们用到了enter()和exit()方法来进行文件的操作。如下图所示,我们可以自定义一个类似with功能的类来实现该功能。

我们可以发现,with Open() as f,可以看做是,就行了一个实例化的过程,它是先执行,enter()方法,再执行with代码块,最后执行了exit()函数,接着才会执行with之后的代码块。
问题1:with代码块中没有异常的情况
没有异常的情况下,直接先Open()进行一个实例化,首先执行enter()方法,并将返回值赋值给f,再执行with代码块,接着是执行eixt()方法,最后是执行with之后的代码块。如下图所示:

问题2.with代码块中有异常
1.系统内部对异常未做任何处理
如果with中出现了异常,代码会怎样运行呢?见下图:

With语句前面部分执行enter()方法不变,接着执行with内部的代码块,其中如果有异常,则在发生异常出直接运行exit()方法,若_exit()方法返回值不为Ture,则并停止整个程序的运行(因为程序遇到了问题,不再往下运行了)
2.系统内部处理了异常
With语句前面部分执行
enter()方法不变,接着执行with内部的代码块,其中如果有异常,则在发生异常处直接运行exit__()方法,若_exit__()方法返回值为Ture,则结束with内部代码,接着执行with之外(之后)的代码块,如下图:

该部分的代码块如下:

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__方法‘)
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return  True
with Open(‘W.txt‘) as f:
    print("执行with代码块")
    print(f.name)
    print(f.value)  #--->错误在此处
    print("执行with最后的代码块")   #--->不执行
print("继续with之后的代码块")

三.有何用途?
1.使用with语句的目的是将代码块放入with中执行,with结束后,会自动完成清理工作(内存清理),无需手动干预。
也就是说,在with结束后会自动关闭文件(使用close方法),我们可以想到,不管有没有异常,with代码块最后都会执行exit()方法,此时我们可以在exit()中完成内存清理工作。
2.在需要管理一些资源如文件、网络连接和锁等编程环境中,我们可以在exit方法中自定义释放资源的机制。该功能会有很大的用处。

原文地址:http://blog.51cto.com/10836356/2111058

时间: 2024-11-05 17:30:59

上下文管理协议的相关文章

Python概念-上下文管理协议中的__enter__和__exit__

所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_val, exc_tb):当with运行结束之后触发此方法的运行 exc_type如果抛出异常,这里获取异常的类型 exc_val如果抛出异常,这里显示异常内容 exc_tb如果抛出异常,这里显示所在位置 代码示例:(以自己定义的Open类型做示例) 1 # 编辑者:闫龙 2 class Open: 3

Python基础- 类和对象(使用、继承、派生、组合、接口、多态、封装、property、staticmethod、classmethod、反射、slots、上下文管理协议、元类)

标签: python对象 2017-07-01 16:28 79人阅读 评论(0) 收藏 举报  分类: python(11)  版权声明:本文为广大朋友交流学习,如有纰漏望不吝赐教,若存在版权侵犯请及时与我联系 目录(?)[+] 一.初识类和对象 在python3中类型就是类 先定义类在产生相对应的对象,也就是现有了概念再有了实体 class Garen: camp = 'Demacia' def attack(self): print('attack') 1.如何使用类 在python3:

关于__setitem__,__getitem__,delitem__以及__slots__,迭代器原理,上下文管理协议还有元类

关于__setitem__,__getitem__,delitem__ 类似于以前的学过的__setattr__,__getattr__... 不同之处在于item结尾的是用于对象以字典添加的形势添加,查看和删除属性的时候才会触发,如下例子: class Foo(object): # __slots__=['x','y'] def __setitem__(self, key, value): print('我在写入') self.__dict__[key]=value def __getitem

python 面向对象编程 之 上下文管理协议

with open('path', 'r' ,encoding='utf-8') as f: 代码块 上述就叫做上线文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法. 上下文管理协议: class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句 ,对象的__enter__被触发,有返回值则赋值给as声明的

Python进阶-----上下文管理协议(__enter__,__exit)

一.上下文管理协议 即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 1.__enter__()会在with语句出现(实例化对象)时执行 2.__exit__()会在with语句的代码块实行完毕才会执行 1 class Open: 2 def __init__(self,name): 3 self.name = name 4 5 def __enter__(self): #在实例化打开文件时即触发,在with时触发 6 print(

python 描述符 上下文管理协议 类装饰器 property metaclass

1.描述符 #!/usr/bin/python env # coding=utf-8 # 数据描述符__get__ __set__ __delete__ ''' 描述符总结 描述符是可以实现大部分python类特性中的底层魔法,包括@classmethod,@staticmethd,@property甚至是__slots__属性 描述符是很多高级库和框架的重要工具之一,描述符通常是使用到装饰器或者元类的大型框架中的一个组件 注意事项: 一 描述符本身应该定义成新式类,被代理的类也应该是新式类 二

上下文管理协议with_open,__enter__和__exit__(三十八)

在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 with obj as f ==========等同于 f = obj.__enter__() class Foo: def __init__(self,name): self.name = name def __enter__(self): print("出现wit

十六. 面向对象上下文管理协议

一. __enter__和__exit__ 我们知道在操作文件对象的时候可以这么写 1 with open('a.txt') as f: 2 '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 # 上下文管理协议 class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__

python 上下文管理协议

class Foo: 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') print(exc_tb) #name print(exc_type) print(exc_val) #Traceback return True #返回TURE后,涵