python的with语法的深入理解
如果你有一些对象(比如一个文件、网络连接或锁),需要支持 with 语句,下面介绍两种定义方法。
方法(1):
首先介绍下with 工作原理
(1)紧跟with后面的语句被求值后,返回对象的“__enter__()”方法被调用,这个方法的返回值将被赋值给as后面的变量;
(2)当with后面的代码块全部被执行完之后,将调用前面返回对象的“__exit__()”方法。
with工作原理代码示例:
class Sample:
def __enter__(self):
print "in __enter__"
return "Foo"
def __exit__(self, exc_type, exc_val, exc_tb):
print "in __exit__"
def get_sample():
return Sample()
with get_sample() as sample:
print "Sample: ", sample
代码的运行结果如下:
in __enter__
Sample: Foo
in __exit__
可以看到,整个运行过程如下:
(1)enter()方法被执行;
(2)enter()方法的返回值,在这个例子中是”Foo”,赋值给变量sample;
(3)执行代码块,打印sample变量的值为”Foo”;
(4)exit()方法被调用;
【注:】exit()方法中有3个参数, exc_type, exc_val, exc_tb,这些参数在异常处理中相当有用。
exc_type: 错误的类型
exc_val: 错误类型对应的值
exc_tb: 代码中错误发生的位置
示例代码:
class Sample():
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print "type: ", exc_type
print "val: ", exc_val
print "tb: ", exc_tb
def do_something(self):
bar = 1 / 0
return bar + 10
with Sample() as sample:
sample.do_something()
程序输出结果:
in enter
Traceback (most recent call last):
type: <type 'exceptions.ZeroDivisionError'>
val: integer division or modulo by zero
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 36, in <module>
tb: <traceback object at 0x7f9e13fc6050>
sample.do_something()
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 32, in do_something
bar = 1 / 0
ZeroDivisionError: integer division or modulo by zero Process finished with exit code 1
方法(2):
实现一个新的上下文管理器的最简单的方法就是使用 contexlib 模块中的 @contextmanager 装饰器。 下面是一个实现了代码块计时功能的上下文管理器例子:
import time
from contextlib import contextmanager @contextmanager
def timethis(label):
start = time.time()
try:
yield
finally:
end = time.time()
print('{}: {}'.format(label, end - start))
# Example use
with timethis('counting'):
n = 10000000
while n > 0:
n -= 1
在函数 timethis() 中,yield 之前的代码会在上下文管理器中作为 __enter__() 方法执行, 所有在 yield 之后的代码会作为 __exit__() 方法执行。 如果出现了异常,异常会在yield语句那里抛出。
【注】
1、@contextmanager 应该仅仅用来写自包含的上下文管理函数。
2、如果你有一些对象(比如一个文件、网络连接或锁),需要支持 with 语句,那么你就需要单独实现 __enter__() 方法和 __exit__() 方法。
python的with语法的深入理解的更多相关文章
- Python的基础语法(二)
0. 前言 接着上一篇博客的内容,我将继续介绍Python相关的语法.部分篇章可能不只是简单的语法,但是对初学者很有帮助,也建议读懂. 1. 表达式 由数字.符号.括号.变量等组成的组合. 算术表达式 ...
- 五. Python基础(5)--语法
五. Python基础(5)--语法 1 ● break结束的是它所在的循环体, continue是让它所在的循环体继续循环 # 打印: 1 10 2 10 3 10 4 10 5 10 6 10 7 ...
- python关键的语法
python关键的语法 1.标准类型分类
- 从Python安装到语法基础,这才是初学者都能懂的爬虫教程
Python和PyCharm的安装:学会Python和PyCharm的安装方法 变量和字符串:学会使用变量和字符串的基本用法 函数与控制语句:学会Python循环.判断语句.循环语句和函数的使用 Py ...
- pycharm的基本使用 、 Python的注释语法,变量,常量,垃圾回收机制,数据类型
1.文件路径要注意 我把文件放在了D盘,如下图:你们可以根据自身情况设置 2.python环境要选择本地下载好的 如下图: 点击本机存在的环境,如果提示NO interpr,就点击第二步 如果还是没有 ...
- python yield from 语法
python yield from 语法 yield语法比较简单, 教程也很多 , yield from的中文讲解很少 , python官网是这样解释的 PEP 380 adds the yield ...
- Python基础:语法基础(3)
本篇主要介绍Python中一些基础语法,其中包括:标识符.关键字.常量.变量.表达式.语句.注释.模块和包等内容. 1. 标识符和关键字 1.1 标识符 标识符是变量.常量.函数.属性.类.模块和包等 ...
- 六. Python基础(6)--语法
六. Python基础(6)--语法 1 ● Python3中, Unicode转字节的方法 print(bytes("李泉", encoding = 'utf-8')) prin ...
- 四. Python基础(4)--语法
四. Python基础(4)--语法 1 ● 比较几种实现循环的代码 i = 1 sum = 0 while i <= 10: # 循环10-1+1=10次 sum += i i ...
随机推荐
- 剑指offer 面试题8:二叉树的下一个节点
题目:给定一棵二叉树和其中一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右节点的指针,还有一个节点指向父节点的指针. 中序遍历序列是{d,b,h,e,i,a,f,c,g} ...
- 网络协议 9 - TCP协议(下)
上次了解了 TCP 建立连接与断开连接的过程,我们发现,TCP 会通过各种“套路”来保证传输数据的安全.除此之外,我们还大概了解了 TCP 包头格式所对应解决的五个问题:顺序问题.丢包问题.连接维护. ...
- connect ECONNREFUSED 127.0.0.1:80错误解决
这个报错也是一直困扰了我许久,服务端一直打印这个报错,但是页面数据响应又都正常,起初真不知道是因为什么原因,能看出来他是在调用80端口, 但是不明白为什么会调用80端口.一度以为是config.js里 ...
- 第01组 Alpha事后诸葛亮
目录 一.总结思考 1.设想和目标 ①我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? ②我们达到目标了么(原计划的功能做到了几个? 按照原计划交付时间交付了么? 原 ...
- java线程池源码的理解
线程池 新建线程和切换线程的开销太大了,使用线程池可以节省系统资源. 线程池的关键类:ThreadPoolExecutor. 该类中包含了大量的多线程与并发处理工具,包括ReentrantLock.A ...
- express框架,使用 static 访问 public 内静态文件
使用 express 生成 node 服务器后,我们需要访问放在public文件夹内的静态文件,如上传的图片 我们需要在app.js中添加配置项: app.use('/public',express. ...
- 修改ARP缓存表大小
在下发Mininet的ARP缓存表表项时,出现了如下的错误信息: SIOCSARP: No buffer space available 这是由于ARP表是缓存在内存中的,超过了系统对ARP缓存表大小 ...
- AKKA Inbox收件箱
起因 得到ActorRef就可以给actor发送消息,但无法接收多回复,也不知道actor是否停止 Inbox收件箱出现就是解决这两个问题 示例 package akka.demo.actor imp ...
- AKKA事件机制
AKKA Event Bus 事件机制就用于当前运行环境,与集群环境不同,详细见AKKA 集群中的发布与订阅Distributed Publish Subscribe in Cluster 简单实现示 ...
- Lua函数声明与调用
lua编程中,我们经常也会遇到函数的声明定义和调用. [1]lua中函数定义与调用的方法 lua有两种函数定义和调用的方法(本质都是用属性,方式不同而已): (1)点号形式 (2)冒号形式 两种方法的 ...