有次面试被问到如何优雅地打开一个文件?
 
那就是用with语句,调用过后可以自动关闭。
 
但是为什么使用with语句就可以自动关闭呢,原因就是上下文管理协议。
 
上下文管理协议:包含方法 __enter__() 和 __exit__(),支持该协议的对象要实现这两个方法。
with open('a.txt', 'r') as a, open('b.txt', 'w') as b:
b.write(a.read()) 
 
读取文件with语句的实现及其调用过程:
class ReadFile(object):
def __init__(self, filename):
self.file = open(filename, 'r') def __enter__(self):
return self.file def __exit__(self, type, value, traceback):
# type, value, traceback 分别代表错误的类型、值、追踪栈
self.file.close()
# 返回 True 代表不抛出错误,否则错误会被 with 语句抛出
return True with ReadFile('test.txt') as file_read:
for line in file_read.readlines():
print(line)
 
 
在调用的时候:
  1、with语句先暂存了ReadFile类的__exit__方法
  2、然后调用ReadFile类的__enter__方法
  3、__enter__方法打开文件,并将结果返回给with语句
  4、上一步的结果被传递给file_read参数
  5、在with语句内对file_read参数进行操作,读取每一行
  6、读取完成之后,with语句调用之前暂存的__exit__方法
  7、__exit__方法关闭了文件
 
要注意的是,在__exit__方法内,我们关闭了文件,但最后返回True,所以错误不会被with语句抛出。否则with语句会抛出一个对应的错误。
 
  当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险。

用python优雅打开文件及上下文管理协议的更多相关文章

  1. Python上下文管理协议:__enter__和__exit__

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语 ...

  2. python深浅拷贝&垃圾回收&上下文管理(with语句)

    深浅拷贝 在Python中使用copy模块用于对象的拷贝操作. 该模块提供了两个主要的方法:浅拷贝 copy.copy() 深拷贝 copy.deepcopy() 1.浅拷贝(copy) 浅拷贝: 不 ...

  3. Python 上下文管理协议中的__enter__和__exit__基本理解

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  4. Python概念-上下文管理协议中的__enter__和__exit__

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  5. python上下文管理协议

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  6. python 描述符 上下文管理协议 类装饰器 property metaclass

    1.描述符 #!/usr/bin/python env # coding=utf-8 # 数据描述符__get__ __set__ __delete__ ''' 描述符总结 描述符是可以实现大部分py ...

  7. Python全栈day28(上下文管理)

    我们知道在操作文件对象的时候可以这么写 with open('a.txt',''r) as f: 代码 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明 ...

  8. Python中的with语句(上下文管理协议)

    在平时工作中总会有这样的任务,它们需要开始前做准备,然后做任务,然后收尾清理....比如读取文件,需要先打开,读取,关闭 这个时候就可以使用with简化代码,很方便 1.没有用with语句 f = o ...

  9. python - 上下文管理协议(with + __enter__ + __exit__)

    上下文管理协议: with + __enter__ + __exit__ #上下问管理协议: #with + __enter__ + __exit__ class Test(): def __init ...

随机推荐

  1. cut语法2

    linux每日一命令--cut--按文件大小排序 显示前100行 显示后五列 ll -Sh|head -n 100|cut -d ' ' -f 5- 一.基本语法cut是一个选取命令,以行为单位,用指 ...

  2. nginx下运行php的程序时返回200访问却是空白页问题的解决方法

    由于nginx与php-fpm之间的一个小bug,会导致这样的现象: 网站中的静态页面 *.html 都能正常访问,而 *.php 文件虽然会返回200状态码, 但实际输出给浏览器的页面内容却是空白. ...

  3. js使页面重定向

    location.assign("http://www.baidu.com"); window.location="http://www.baidu.com"; ...

  4. “必须执行Init_Clk函数,才能采集到二氧化碳接口485数据的问题”的解决

    这个问题困扰了我很长一段时间,而且如果这个问题不解决,就有一个无法调和的矛盾:执行Init_Clk函数,能采集到二氧化碳接口485数据,但是功耗大:不执行Init_Clk函数,不能采集到二氧化碳接口4 ...

  5. 【坑】https证书链不完整的坑

    支付宝支付回调https失败,微信分享https连接在微信里打开空白,而chrome等浏览器访问正常. 是的,以上问题我作为半个运维在项目中遇到了,就是由于https证书链不完整引起的. 好吧,其实压 ...

  6. c# android 全局捕获未处理异常

    [Application] public class MyApp : Application { public MyApp(IntPtr javaReference, JniHandleOwnersh ...

  7. 策略模式(Strategy )

    为实现一个目的采用不同的方式都可实现,具体看要采取哪种方式. //接口 public interface Strategy {    public void algorithmInterface(); ...

  8. 二、tcp/ip基础知识

    一.TCP/IP的标准化 1.TCP/IP的含义 一般来说,TCP/IP是利用IP进行通信时所必须用到的协议群的统称. 具体点,IP或ICMP.TCP或UDP.TELENT或FTP.以及HTTP等都属 ...

  9. SSH原理及操作

    1:公钥与私钥(public and private key) 公钥:提供给远程主机进行数据加密的行为 私钥:远程主机收到客户端使用公钥加密数据后,在本地端使用私钥来解密 2:公钥与私钥进行数据传输时 ...

  10. 深入理解CSS系列(一):理解CSS的盒子模型

    接触前端也有好几个年头了,但是,讲实话,对于CSS的理解真的是不敢恭维,相信很多同行也有类似的感受吧!这是为什么呢?因为我们都认为CSS太简单了,没有必要深入学习,果真如此?其实,只不过是自己图样图森 ...