博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python之with语句原理
阅读量:6712 次
发布时间:2019-06-25

本文共 1628 字,大约阅读时间需要 5 分钟。

我们看一个with处理文件操作的实例:

with open('/etc/passwd') as f:    for line in f:        print(line)

这段代码的作用:打开一个文件,如果一切正常,把文件对象赋值给f,然后用迭代器遍历文件中每一行,当完成时,关闭文件;

而无论在这段代码的任何地方,如果发生异常,此时文件仍会被关闭。

 

with看起来如此简单,但是其背后还有一些工作要做,因为你不能对Python的任意对象使用with语句,它仅能工作于支持上下文管理协议(context management protocol)的对象。

也就是说,只有内建了“上下文管理”的对象可以和with一起工作,目前支持该协议的对象有:

  • file
  • decimal.Context
  • thread.LockType
  • threading.Lock
  • threading.RLock
  • threading.Condition
  • threading.Semaphore
  • threading.BoundedSemaphore

 

当with语句执行时,便执行上下文表达式(context_expr)来获得一个上下文管理器,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节:

一旦获得了上下文对象,就会调用它的__enter__()方法,将完成with语句块执行前的所有准备工作,如果with语句后面跟了as语句,则用__enter__()方法的返回值来赋值;

当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,__exit__()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。

因为上下文管理器主要作用于共享资源,__enter__()和__exit__()方法干的基本是需要分配和释放资源的低层次工作,

比如:数据库连接、锁分配、信号量加/减、状态管理、文件打开/关闭、异常处理等。

 

知道了上面这些,我们就可以尝试在自定义类里面创建__enter__()和__exit__()方法,来配合with语句创建类实例了:

class A:    def __enter__(self):        print('__enter__() is called')    def __exit__(self, e_t, e_v, t_b):        print('__exit__() is called')with A() as a:    print('got instance')

  输出:

 

另外python库中还有一个模块contextlib,使你不用构造含有__enter__, __exit__的类就可以使用with:

from __future__ import with_statementfrom contextlib import contextmanager@contextmanagerdef context():    print('entering the zone')    try:        yield    except Exception as e:        print('with an error %s'%e)        raise e    else:        print('with no error')with context():    print('----in context call------')

  输出:

 

转载于:https://www.cnblogs.com/wumingxiaoyao/p/7132181.html

你可能感兴趣的文章
做个聪明人,聪明的工作,在工作中自我培养
查看>>
关于android中PendingIntent.getBroadcase的注册广播
查看>>
jquery 判断多选框被勾选的个数
查看>>
ubuntu 安装oracle jdk
查看>>
Linxu最最使用命令
查看>>
JS的并行加载与执行顺序
查看>>
Linux下安装Hadoop(伪分布模式)
查看>>
Android UI设计准则
查看>>
IntelliJ IDEA 2017.3.1 使用手册
查看>>
互联网协议入门(2)
查看>>
DataSource的可配参数有哪些,有哪些DataSource可以用
查看>>
免费的后台管理界面框架
查看>>
本地文件共享服务(nfs samba ftp)
查看>>
scp通过代理proxy传输文件
查看>>
excel 打开时报“发现不可读的内容...”
查看>>
pandas-利用python进行数据分析
查看>>
数据段、代码段、堆栈段、BSS段的区别
查看>>
Apache Bench
查看>>
WebService之Axis2快速入门(5): 管理会话(Session)
查看>>
以太坊RPC接口使用
查看>>