本文先介绍with表达式,然后再试图用with以及装饰器等知识实现自己的ContextManager
with可以干什么?我的理解是简化try except finally的工作,比如打开文件操作符,读文件,捕捉异常,最后关闭。这个例子是with最最常用的方法了,满大街都可以找到这个例子。
除文件open操作之外,其实其它很多操作也可以掐头去尾,留下中间关键操作就行。
那么该如何实现呢?按照python文档解释,只要实现__enter__和__exit__两个函数就可以。
很简单:
class ConMgr(object):
def __init__(self):
print("__init__ called")
def __call__(self, *args):
print("__call__ called")
#: 可以把传进来的参数保存着,在with开始时运行
self.args = args
return self
def __enter__(self):
# 打印之前传进来的参数
print("__enter__ called", self.args)
return 'abcd'
def __exit__(self, exc_type, exc_val, exc_tb):
print("__exit__ called: exc_type = %s exc_val = %s exc_tb = %s "\
% (exc_type, exc_val, exc_tb))
return "exited"
def test1():
c = ConMgr()
with c('pppp') as tmp:
print(tmp)
print("haha")
assert 1>2
print(3)
test1()
输出结果是:
__init__ called
__call__ called
('__enter__ called', ('pppp',))
abcd
haha
__exit__ called: exc_type = <type 'exceptions.AssertionError'> exc_val = exc_tb = <traceback object at 0x7f911003b128>
首先请注意,这里的c()是类的一个实例,就是一个普通类,而不是generator。当c('pppp')执行时,调用了__call__函数,__call__函数赶紧把传入的参数保存了下来,等进了with块之后,调用__enter__之时再把参数放出来。
另外__call__函数一定要返回self,因为with块运行完了之后,将会调用self.__exit__()如果不返回self将找不到__exit__函数。
然后就是as语句的tmp值实际上是__enter__的返回值,返回什么都可以,无所谓的,哪怕传个闭包。这里的好主意是把之前的args可以传给tmp。
最后请仔细看,当assert 1>2发生错误之后,with块没有执行完就调用__exit__函数了。通过这个函数的参数,我们来实现异常处理。
接下来介绍下python的contextlib这个模块。
可能有朋友不知到,这个模块没有主轴功能,主要是围绕with语句,提供了一些方便的util函数操作。
这个模块里面有一个contextmanager的装饰器,它可以省掉我们之前那么麻烦创建一个class然后补上__enter__和__exit__的过程,它利用工厂模式生成一个generator,然后就可以方便的使用with语句了。
关于官方contextlib模块里面的功能,我想自己能不能做一个山寨版出来,详细见
下文
分享到:
相关推荐
主要介绍了Python 中的with关键字使用详解的相关资料,在Python中,with关键字是一个替你管理实现上下文协议对象的好东西,需要的朋友可以参考下
说起js中的with关键字,很多小伙伴们...在js高级程序设计中是这样描述with关键字的:with语句的作用是将代码的作用域设置到一个特定的作用域中,基本语法如下: with (expression) statement; 使用with关键字的目的是
主要介绍了Python with关键字,上下文管理器,@contextmanager文件操作,结合实例形式分析了Python使用with关键字及上下文管理器、contextmanager进行文件打开、读写、关闭等操作的相关实现技巧,需要的朋友可以参考下
2009年12月,ECMAScript发布了ECMAScript 5,这距离上一个版本的ECMAScript 3标准发布已经整整十年了,其间JavaScript虽然大行于web编程,ECMAScript 4却最终因为利益相关的各大厂商和组织在此语言的复杂性(即是否...
在Python中,with关键字是一个替你管理实现上下文协议对象的好东西。例如:file等。示例如下: from __future__ import with_statement with open('cardlog.txt','r') as item : for line in item : print ...
用C#写的KWIC系统,控制台程序。关键字上下文检索
python关键字(简) >>> import keyword >>> keyword.kwlist ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', '...
进阶版:改良版本的程序是对可能发生异常的代码处进行 try 捕获,使用 try/finally 语句,该语句表示如果在 try 代码块中程序出现了异常,后续代码
主要介绍了关于python中关键字"with"和上下文管理器的相关资料,文中介绍的非常详细,相信对大家学习或者使用python具有一定的参考价值,需要的朋友们下面来一起看看吧。
build a string with wildcards CString strWildcard pstr ; strWildcard + T " " ; start working for files BOOL bWorking finder FindFile strWildcard ; while bWorking&&bRun { ...
c# 动态编译代码 执行脚本代码 关键字还会变色 // debug it step by step (F10, F11) using System; // for Console.WriteLine using System.Windows.Forms; // for MessageBox.Show, ... using System....
表达式计算器是一个由C++ with QT编写的应用程序。这个计算器旨在通过引入表达式计算的概念解决Windows默认计算器显示不直观的问题,提供了普通型计算器、科学型计算器的功能,并且可以通过页面管理机制快速添加...
java关键字源码到Java10 翻译Java源代码以使用jdk的10 var关键字。 使用尊贵的生成解析器和侦听器。 建造 编译jar或从发行版中下载(如果可用): mvn package ls -la target/ ... toJava10.jar 用法 将其指向,默认...
关键字驱动的Selenium测试 ####################微笑测试################### Written by Andreas Popp For more informations visit https://test-with-a-smile.de or mailto andreas.popp@testautomation-popp...
深度学习框架Keras作者编写的,低门槛、超详细深度学习入门书籍。