笔记-python-lib-contextlib

1.      contextlib

with 语句很好用,但不想每次都写__enter_-和__exit__方法;

py标准库也为此提供了工具模块contextlib

模块提供的功能有很多,重点说一下contextmanager

2.      contextmanager

它提供了一个简单的上下文环境

简单使用:

from contextlib import contextmanager

@contextmanager

def make_open_context(filename, mode):

fp = open(filename, mode)

try:

yield fp

finally:

fp.close()

with make_open_context('i002.txt','a') as fi:

fi.write('hello ')

不用创建类和写__enter__,__exit__方法。

2.1.    代码释义

def contextmanager(func):

"""@contextmanager decorator.

Typical usage:

@contextmanager

def some_generator(<arguments>):

<setup>

try:

yield <value>

finally:

<cleanup>

This makes this:

with some_generator(<arguments>) as <variable>:

<body>

equivalent to this:

<setup>

try:

<variable> = <value>

<body>

finally:

<cleanup>

"""

@wraps(func)

def helper(*args, **kwds):

return _GeneratorContextManager(func, args, kwds)

return helper

contextmanager是一个装饰器函数,去掉注释,实际上是返回一个中间函数helper,helper返回的则是一个上下文管理器,具体的实现可以看下代码。

2.2.    _GeneratorContextManager(func, args, kwds)

前序准备工作非常简单,主要是后续清理代码比较多。

def __enter__(self):

try:

return next(self.gen)

except StopIteration:

raise RuntimeError("generator didn't yield") from None

def __exit__(self, type, value, traceback):

if type is None:

try:

next(self.gen)

except StopIteration:

return False

else:

raise RuntimeError("generator didn't stop")

else:

if value is None:

# Need to force instantiation so we can reliably

# tell if we get the same exception back

value = type()

try:

self.gen.throw(type, value, traceback)

except StopIteration as exc:

# Suppress StopIteration *unless* it's the same exception that

# was passed to throw().  This prevents a StopIteration

# raised inside the "with" statement from being suppressed.

return exc is not value

except RuntimeError as exc:

# Don't re-raise the passed in exception. (issue27122)

if exc is value:

return False

# Likewise, avoid suppressing if a StopIteration exception

# was passed to throw() and later wrapped into a RuntimeError

# (see PEP 479).

if type is StopIteration and exc.__cause__ is value:

return False

raise

except:

# only re-raise if it's *not* the exception that was

# passed to throw(), because __exit__() must not raise

# an exception unless __exit__() itself failed.  But throw()

# has to raise the exception to signal propagation, so this

# fixes the impedance mismatch between the throw() protocol

# and the __exit__() protocol.

#

if sys.exc_info()[1] is value:

return False

raise

raise RuntimeError("generator didn't stop after throw()")

3.      参考文档

参考文档:https://docs.python.org/3/library/contextlib.html?highlight=contextlib#module-contextlib

最新文章

  1. python框架之django
  2. http协议(五)web服务器
  3. (404) 未找到 获取StatusCode状态码
  4. Linux系统软件
  5. jQuery 显示加载更多(节流) 实现预加载
  6. IT技术开发人员35岁之前应该做的十件事
  7. 如何重写EF DBContext 获取链接字符串的方法
  8. 新买一款打印机hp5525N
  9. Tensorflow之卷积神经网络(CNN)
  10. 小白突破百度翻译反爬机制,33行Python代码实现汉译英小工具!
  11. call(),apply()方法解析(一)
  12. 安装cmake
  13. Python3 Win下安装 scipy
  14. js的微任务和宏任务
  15. js的基本包装类型
  16. ArcGIS案例学习笔记2_1_山顶点提取最大值提取
  17. 虚拟机安装oracle重新启动后oracle em起不来 ORA-01034: ORACLE not available
  18. 【转】如何用Redis做LRU-Cache
  19. Linux下pppoe设置
  20. 20145105 《Java程序设计》实验二总结

热门文章

  1. React 复合组件
  2. 【起航计划 029】2015 起航计划 Android APIDemo的魔鬼步伐 28 App-&gt;Preferences-&gt;Default Values 偏好默认值
  3. selenium grid 使用方法
  4. 变更hostname
  5. Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)
  6. SQL Server(第一章) 创建表 删除表 创建主键约束、唯一约束、外键约束、CHECK约束、默认约束
  7. ListView、DataGrid 不显示列标题
  8. Python 类的高级属性(可选)
  9. Vsftpd服务传输文件(转)
  10. FastRCNN 训练自己数据集 (1编译配置)