Python中的with是测试常用到的资源打开利
“在我们完成自动化测试代码的时候,总会遇见各种读取文本文件、读取Excel等类型的操作。这种代码我们时刻都要记得打开文件后要关闭文件。往往关闭文件却是我们常常忘记的。针对上述这样的情况,python提供了with就可以完美解决这个问题,这也是python的语法糖。Syntactic sugar,也就是语法糖,它指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。语法糖就是为了避免coder出现错误并提高效率的语法层面的一种优雅的解决方案。 ”
一个常规的文件打开代码
下面是一个常规的打开文件的代码,那么你可以从下面代码中看出什么问题吗?
rf= open('crisschan.txt','r')
print(rf.readlines())
rf.close()
上面代码在读取文件过程中如果发生异常,那么close()函数就没有办法被执行到了,这也就导致了文件没有办法关闭了。因此,很多教程上都告诉大家要用try except将文件读取的异常捕获到,那么我们改造一下如下:
try:
rf = open('email.txt','r')
print(rf.readlines())
except:
print('Oooooops!What's up!')
finally:
rf.close()
好了,上面的代码无论如何我们都会执行close函数了,这样是不是已经很好了。但是上面的代码太繁琐了,这样的coding段,python提供了with,让上述的代码更简单:
with open('email.txt','r') as rf:
print(rf.readlines())
上面是不是很简洁,是不是也很优雅呢。
with是怎么干活的
with context_expression [as target(s)]:
do_somthing()
上述代码片段中,context_expression
会返回一个上下文管理器对象,这个对象并不赋值给as
后的target(s)
,而是上下文管理器的__enter__()
函数的返回值赋值给 target(s)
。当with全部的代码段都执行完成后,会调用__exit__()
。
具体例子如下:
class SampleWith(object):
def __init__(self):
print('init this class')
def __enter__(self):
print('this is __enter__')
return 'CrissChan'
def __exit__(self, exc_type, exc_val, exc_tb):
print('this is __exit__')
def call(self):
print('call funtion')
if __name__ == '__main__':
with SampleWith() as sw:
print('sw is :',sw)
sw.call()
运行完后,输入如下:
init this class
this is __enter__
sw is : CrissChan
this is __exit__
Traceback (most recent call last):
File "/Users/crisschan/PycharmProjects/try_space/flv2mp4.py", line 24, in <module>
sw.call()
AttributeError: 'str' object has no attribute 'call'
那下面我来给你解释一下上面的代码段以及结果输出。
- 1、在main函数中我们使用with调用了SampleWith(),这时候我们就会看到了,我们先实例化了一个SampleWith类,调用了他的
__init__(self)
构造函数, - 2、接下来因为我们使用了with这个语法糖,因此下面调用了
__enter__(self)
- 3、在后面我使用了
as sw
,也就是我将__enter__(self)
的return赋值给了sw
,那么也就是说sw
存储的是字符串CrissChan
,那么也就打印了sw is : CrissChan
- 4、后面调用了sw.call()就出了问题,因为字符串没有call方法。但是仍旧进入了
__exit__(self, exc_type, exc_val, exc_tb)
函数。
下面我将上面有报错的代码修改一下,如下:
class SampleWith(object):
def __init__(self):
print('init this class')
def __enter__(self):
print('this is __enter__')
return 'CrissChan'
def __exit__(self, exc_type, exc_val, exc_tb):
print('this is __exit__')
def call(self):
print('call funtion')
if __name__ == '__main__':
with SampleWith() as sw:
print('sw is :',sw)
上面代码就不会报错了。从上面可以看出就算中间除了异常,放在__exit__()
中的逻辑段还是会被执行的。想要了解更多请看官方的文档pep-403
特别备注:
exit()方法中有3个参数, exc_type, exc_val, exc_tb,这些参数在异常处理中相当有用。
exc_type: 错误的类型
exc_val: 错误类型对应的值
exc_tb: 代码中错误发生的位置
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 爬虫(七):pyspider 使用
- 你的童年有俄罗斯方块吗?教你用 Python 实现俄罗斯方块!
- Python 基础(七):字典与集合
- 5 分钟教你用 Python 实现贪吃蛇!
- Python 基础(八):与时间相关的模块
- 用 Python 实现一场环保无污染的烟花秀
- Python 基础(九):函数
- Python 基础(十二):文件基本操作
- Python 基础(十三):os 模块
- Python 基础(十四):错误和异常
- Python 基础(十五):枚举
- 一个老程序员的30年生涯回顾
- 经典 90 坦克大战 Python 版实现(支持单双人模式)
- Python 基础(十六):迭代器与生成器
- MySQL information_schema详解 COLUMNS