博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础知识回顾——上下文管理器
阅读量:4511 次
发布时间:2019-06-08

本文共 2100 字,大约阅读时间需要 7 分钟。

上下文管理机制

很多情况,当我们使用完一个资源后,我们需要手动的关闭掉它,比如操作文件,建立数据库连接等。但是,在使用资源的过程中,如果遇到异常,很可能错误被直接抛出,导致来不及关闭资源。所以在大部分时候,我们使用”try-finally”语句来确保资源会关闭。

1 try:2     f = open('test.txt', 'w+')3     print(f.closed)        #判断文件是否关闭4     f.write('Hello World!')5 finally:6     f.close()7     print(f.closed)        #判断文件是否关闭

运行结果:

FalseTrue   

Python语言里提供的with语句功能几乎同”try-finally”一样,代码更简洁。

1 with open("test.txt", "w") as f:2     print(f.closed)3     f.write("Hello World!")4 print(f.closed)

运行结果:

FalseTrue

以上即是上下文管理器的用法,Python要求在with语句进入时自动调用__enter__()方法,其返回值会赋给as关键字后的变量;在with语句块退出后自动调用__exit__()方法。对于文件对象f来说,它定义了__enter__()和__exit__()方法(可以通过dir(f)看到)。在f的__exit__()方法中,有self.close()语句,这样就不用明文写f.close()了。

 

自定义上下文管理器

要自定义类似with语句的类,其内部必须提供两个内置方法__enter__以及__exit__。前者在主体代码执行前执行,后则在主体代码执行后执行。__enter__()返回的一对象作为as所指的变量。

1 class ContextManagerDemo(object): 2     def __init__(self,text): 3         self.text = text 4  5     def __enter__(self): 6         self.text = "I say: " + self.text 7         #print self     <__main__.ContextManagerDemo object at 0x023557D0> 8         return self 9 10     def __exit__(self, exc_type, exc_val, exc_tb):  11         self.text = self.text + "!"12 #参数exc_type, exc_val, exc_tb分别代表异常类型,异常值,和异常的Traceback。当处理完异常后,可以让”__exit__()”方法返回True,此时该异常就不会再被抛出。正常程序中三个参数都是None13 14 with ContextManagerDemo('hello') as f:      #上下文管理器会使用__enter__()返回的这一对象作为as所指的变量f,如果没有返回对象,text属性则无法调用15     print f.text16 17 print f.text

运行结果:

1 I say: hello2 I say: hello!

 

上下文管理器应用

1.管理多个文件

1 with open('data.txt') as source, open('target.txt', 'w') as target:2             target.write(source.read())

2.管理数据库游标

1 import pymysql  2  3 def get_conn(**kwargs):  4   return pymysql.connect(host=kwargs.get('host', 'localhost'),                  port=kwargs.get('port', 8080),                  user=kwargs.get('user'),                  passwd=kwargs.get('passwd'))  5  6 def main():  7   conn = get_conn(user='Admin', passwd='123456')  8   with conn as cur:  9      cur.execute('show databases')10      print cur.fetchall()11 12  if __name__ == '__main__':13    main()

 

转载于:https://www.cnblogs.com/Ryana/p/6249795.html

你可能感兴趣的文章
[C#]C#中ToString()和Convert.ToString()的区别
查看>>
java作业-窗口的切换
查看>>
【算法与数据结构专场】堆排序是什么鬼?
查看>>
Java中运算符“|”和“||”以及“&”和“&&”区别
查看>>
POJ1026 Cipher
查看>>
JSP-Runoob:JSP开发环境搭建
查看>>
python--对函数的理解
查看>>
基于js原生封装的点击显示完整文字
查看>>
React组件设计技巧
查看>>
androidDecorView、自定义title
查看>>
Java遍历List5种方法的效率对比
查看>>
python 002 文件输入输出
查看>>
HDU 2844 多重背包
查看>>
常用数据库
查看>>
luoguP1390 公约数的和 数学推导_双倍经验
查看>>
(转)JSON Web Token - 在Web应用间安全地传递信息
查看>>
HTTP的请求方法OPTIONS
查看>>
eclipse IDE usage of my own and tutorials link list
查看>>
五笔学习早期笔记
查看>>
LeetCode #24 Swap Nodes in Pairs
查看>>