广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python中的__enter__ __
  • 638
分享到

python中的__enter__ __

python 2023-01-30 22:01:34 638人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理。在Python中实现了__enter__和__exit__方法,即支持上下文管理器协议。上下文管理器就是支持上下文管理器协议的对象,它是为了with而生。当with语

我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理。在Python中实现了__enter__和__exit__方法,即支持上下文管理器协议。上下文管理器就是支持上下文管理器协议的对象,它是为了with而生。当with语句在开始运行时,会在上下文管理器对象上调用 __enter__ 方法。with语句运行结束后,会在上下文管理器对象上调用 __exit__ 方法

with的语法:

with EXPR as VAR:
BLOCK


这是上面语法的伪代码:

mgr = (EXPR)   
exit = type(mgr).__exit__  # Not calling it yet
value = type(mgr).__enter__(mgr)    
exc = True     
try:
    try:
        VAR = value  # Only if "as VAR" is present
        BLOCK
    except:
        # The exceptional case is handled here
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
        # The exception is swallowed if exit() returns true
finally:
    # The nORMal and non-local-Goto cases are handled here
    if exc:
        exit(mgr, None, None, None)


1、生成上下文管理器mgr
2、如果没有发现__exit__, __enter__两个方法,解释器会抛出AttributeError异常
3、调用上下文管理器的 __enter__() 方法
4、如果语法里的as VAR没有写,那么 伪代码里的 VAR= 这部分也会同样被忽略
5、如果BLOCK中的代码正常结束,或者是通过break, continue ,return 来结束,__exit__()会使用三个None的参数来返回
6、如果执行过程中出现异常,则使用 sys.exc_info的异常信息为参数调用 __exit__(exc_type, exc_value, exc_traceback)


之前我们对文件的操作是这样的:

try:
    f = open('filename')
except:
    print("Unexpected error:", sys.exc_info()[0])
else:
    print(f.readlines())
    f.close()


现在有了with语句可以使代码更加简洁,减少编码量,下面的语句会在执行完后自动关闭文件(即使出现异常也会)。:

with open('example.info', 'r') as f:
    print(f.readlines())


一个例子:

class TmpTest:
    def __init__(self,filename):
        self.filename=filename
    def __enter__(self):
        self.f = open(self.filename, 'r')
       # return self.f
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

test=TmpTest('file')

with test as t:
    print ('test result: {}'.format(t))

返回:

test result: None


这个例子里面__enter__没有返回,所以with语句里的"as t"到的是None,修改一下上面的例子:

class TmpTest:
    def __init__(self,filename):
        self.filename=filename
    def __enter__(self):
        self.f = open(self.filename, 'r')
        return self.f
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

test=TmpTest('file')

with test as t:
    print ('test result: {}'.format(t))

返回:

test result: <_io.TextIOWrapper name='file' mode='r' encoding='cp936'>

 
如果在__init__或者__enter__中抛出异常,则不会进入到__exit__中:

class TmpTest:
    def __init__(self,filename):
        self.filename=filename
        print("__init__")
        raise ImportError
    def __enter__(self):
        self.f = open(self.filename, 'r')
        print("__enter__")
        return self.f
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__exit__")
        self.f.close()

test=TmpTest('file')
with test as t:
    print ('test result: {}'.format(t))


返回:

__init__
Traceback (most recent call last):
  File "D:/pythonScript/LeetCode/leetcode.py", line 14, in <module>
    test=TmpTest('file')
  File "D:/pythonScript/leetcode/leetcode.py", line 5, in __init__
    raise ImportError
ImportError


如果在__exit__中返回True,则不会产生异常:

class TmpTest:
    def __init__(self,filename):
        self.filename=filename
        print("__init__")

    def __enter__(self):
        self.f = open(self.filename, 'r')
        print("__enter__")
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__exit__ {} ".format(exc_type))
        self.f.close()
        return True

test=TmpTest('file')
with test as t:
    print ('test result: {}'.format(t))
    raise ImportError
print("no error")

返回:

__init__
__enter__
test result: <_io.TextIOWrapper name='file' mode='r' encoding='cp936'>
__exit__ <class 'ImportError'>
no error



参考: https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p03_make_objects_support_context_management_protocol.html?highlight=with
        Https://docs.python.org/3/library/stdtypes.html#typecontextmanager
        https://www.python.org/dev/peps/pep-0343/

--结束END--

本文标题: python中的__enter__ __

本文链接: https://www.lsjlt.com/news/179619.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python中的__enter__ __
    我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理。在python中实现了__enter__和__exit__方法,即支持上下文管理器协议。上下文管理器就是支持上下文管理器协议的对象,它是为了with而生。当with语...
    99+
    2023-01-30
    python
  • 如何在python中使用__enter__和__exit__
    如何在python中使用__enter__和__exit__?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python主要用来做什么Python主要应用于:1、Web开发;2、...
    99+
    2023-06-14
  • [Python ] python中文件的
    原文地址: http://blog.163.com/qimeizhen8808@126/ 这女孩写的挺好,有值得学习的地方。   1) 文件的打开和创建,关闭  a)文件的打开和创建 主要有两个open()和file()两个方法。它们的功能...
    99+
    2023-01-31
    文件 Python python
  • Python中的defaultdict
    字典(dictionary)是Python中一种常用的数据类型。不同于其他由数字索引的序列,字典是用"键"(key)来索引的。通常表示为dict(key: val, ...),有以下特征: 键可以是任何不可变(immutable)数据类...
    99+
    2023-01-31
    Python defaultdict
  • python中的asyncore
    在Python中,既可直接使用socket类,也可使用socketserver,asyncore等经过封装的类来进行编码。asyncore这个库中主要包含了两个函数:asyncore.loop([timeout[, use_poll[, m...
    99+
    2023-01-31
    python asyncore
  • python中的whitespace
    python中strip()和split()在无参数的情况下使用whitespace做为默认参数,在帮助文档中对whitespace的解释为6个字符,它们是space, tab, linefeed, return, formfeed, an...
    99+
    2023-01-31
    python whitespace
  • python中的类
    关键字:class含义:带有某些属性和方法的一个集合,可以理解成模板。 object的概念:类的实例。以对应类为模板,创建出来的对象。 如何理解python中的self?1 实例本身,对象。2 可以理解为一个字典变量,内部存的就是对象的数据...
    99+
    2023-01-31
    python
  • Python中的threading
    #!/usr/bin/env python# -*- coding: utf-8 -*-import threading, time#新线程执行的代码:def loop():    print('thread %s is running.....
    99+
    2023-01-31
    Python threading
  • Python中的dict
    # dict # Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 d = {'Michael': 95, 'Bob': 75,...
    99+
    2023-01-31
    Python dict
  • python中的difflib
    #############difflib##############文件差异对比示例1:import difflibtext1 = 'hello westos'text2 = 'hello zhan'text1_lines = text1....
    99+
    2023-01-31
    python difflib
  • python中的__call__
        如果python中的一个类定义了 __call__ 方法,那么这个类它的实例就可以作为函数调用,也就是实现了 () 运算符,即可调用对象协议    下面是一个简单的例子: class TmpTest: def __init...
    99+
    2023-01-30
    python
  • python中的rabbitmq
    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写...
    99+
    2023-01-30
    python rabbitmq
  • python中的basestring
    basestring()说明:basestring是str和unicode的超类(父类),也是抽象类,因此不能被调用和实例化,但可以被用来判断一个对象是否为str或者unicode的实例,isinstance(obj, basestring...
    99+
    2023-01-31
    python basestring
  • python中的input
    python中的input()方法是在控制台可以自己输入数据 比如 :定义变量a = 2 现在可以写成 a = input() 可以自己输入变量a的值 注意:input()返回的值是str字符型的 如果要让输入的数字变为整形,可以使用i...
    99+
    2023-01-31
    python input
  • Python中的finally
    Python中的finally 现代语言一般都内置了对异常处理的支持,其中较为广泛使用的就是try语句了。(by gashero)且一般来说其子句还包含有except和finally。Python从Modula-3语言得到了关于异常处理的...
    99+
    2023-01-31
    Python finally
  • python中的subprocess
     python2.7 源码中的注释(由于能力有限,翻译的不太准确): 这个模块允许您开启进程、连接输入、输出和错误的管道,并获取他们的返回代码。这个模块计划替代一些旧代码,如: os.system、os.spawn*、os.Popen、po...
    99+
    2023-01-31
    python subprocess
  • python中的&&及||
    首先说明一下,在python中是没有&&及||这两个运算符的,取而代之的是英文and和or。其他运算符没有变动。  接着重点要说明的是python中的a.any(),我之所以会涉及到这个函数,是因为我在设计某个分段数值函数...
    99+
    2023-01-31
    python
  • Python中的栈
    在python中,个人理解为栈可以用列表来代替服从FILO:First In Last Out其中入栈为(利用append函数)stack = [] stack.append(<item>)出栈为(利用pop函数)stack....
    99+
    2023-01-31
    Python
  • python中的logging
    python logging模块可能会令人困惑的地方通过参阅python logging模块的代码,发现一些有趣的现象: 1. logging对象其实是一个树形结构,每个创建的logging对象都是root logging对象的孩子结点。当...
    99+
    2023-01-31
    python logging
  • python中的struct
    我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组,字典。但是C语言中有些字节型的变量,在python中该如何实现呢?这点颇为重要,特别是要在网络上进行数据传输的话。python提供了一个struct模块来提供转换。...
    99+
    2023-01-31
    python struct
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作