13.python上下文管理器详解

源代码 2024-9-9 05:32:47 123 0 来自 中国
利用上下文管理器,可以让代码更加优雅简便。固然,上下文的管理器的作用不止于此,它内部的实现机制,能很好的处置惩罚代码非常,提拔代码的复用性
1、先看看最简单的例子,with语句

# 创建一个文件写入字符串“Python”f = open('123.txt', 'w')f.write("python")f.close()# 利用with语句调用上下文实现文件写入利用with open('123.txt', 'w') as f:    f.write('python')with语句的作用:
可以主动管理上下文资源,岂论什么缘故原由跳出with块,都能确保文件精确的关闭,以此来到达释放资源的目标。
2、什么是上下文管理器?

上下文是 context 直译的叫法,在步伐中用来表示代码实行过程中所处的前后情况,好比在文件利用时,文件须要打开关闭,而文件读写利用就处于文件利用的上下文情况中;
上下文管理器,上下文管理器是指在一段代码实行之前,实行一些预处置惩罚的工作,代码实行之后再实行一些清算工作。
上下文管理器中有enter()和 exit() 两个方法,enter()方法在实行 with 背面的语句时实行,一样寻常用来处置惩罚利用前的内容,好比一些创建对象,初始化等; exit() 方法在 with 内的代码实行完毕后实行,一样寻常用来处置惩罚一些善后收尾工作,好比文件的关闭,数据库的关闭等。
3、上下文管理器的原理过程如下:

调用enter()方法,举行预处置惩罚利用
实行用户利用
调用 exit() 方法,完成清算利用
4、上下文管理器的应用场景:

资源管理功能,即文件处置惩罚、网络毗连、数据库毗连等利用时须要关闭资源。
也可以在代码实行前后增长功能,类似于装饰器,好比代码之前做权限验证等。
4.1 数据库毗连

import pymysqlclass DBConnection(object):    def __init__(self,ip,user,passwd,db):        self.ip = ip        self.user = user        self.passwd = passwd        self.db = db    def __enter__(self):        self.conn = pymysql.connect(self.ip, user=self.user, passwd=self.passwd, db=self.db)        self.cur = conn.cursor()        return self.cur    def __exit__(self, exc_type, exc_val, exc_tb):        self.cur.close()        self.conn.close()with DBConnection('192.168.121.xxx', user="xxx", passwd="123456", db="xxx") as cur:    cur.execute("select * from studnet;")    result = cur.fetchall()    print(result)完成DBConnection这个类,每次毗连数据库时,只要简单的调用with语句即可,不须要关心数据库的关闭、非常等
4.2、上下文管理器的非常处置惩罚

class MyOpen(object):    """自界说上下文管理类"""    def __init__(self, file, mode):        self._file = file        self._mode = mode    def __enter__(self):        self._handle = open(self._file, self._mode)        return self._handle    def __exit__(self, exc_type, exc_val, exc_tb):        # print('Type: ', exc_type)        # print('Value:', exc_val)        # print('TreacBack:', exc_tb)        self._handle.close()        print("非常已被处置惩罚")        return True# 读的模式打开文件,举行写利用,不支持with MyOpen('123.txt', 'r') as f:    f.write('python')#输出:非常已被处置惩罚with 语法不仅可以简化资源利用的后续扫除利用,还可以取代 try/finally 举行非常处置惩罚
当with中实行的语句发生非常时,非常信息会被发送到 exit()方法的参数中, exit() 方法有如下三个参数:
exc_type : 非常范例
exc_val : 非常值
exc_tb : 非常回溯追踪
这三个参数都与非常有关,with语句会把非常的exc_type ,exc_val 和exc_tb转达给 exit() 方法,它让exit() 方法来处置惩罚非常 ,假如exit()返回的是True,那么这个非常就被忽略,并按照我们界说的方式举行抛出。假如exit()返回的是True以外的任何东西,那么这个非常将被with语句抛出。
4.3、通过contextlib实现

python内置了contextlib这个模块用于实现上下文管理器,它是通过天生器yield实现的,这个模块让我们不必创建类和enterexit了。
from contextlib import contextmanager@contextmanagerdef diy_open(filename, **kwargs):    f = open(filename, **kwargs)    try:        yield f    finally:       f.close()with diy_open('test.txt', encoding='utf-8') as f:    print(f.readlines())
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-12-4 16:48, Processed in 0.105668 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表