Python上下文管理器协议实现详解:__enter__与__exit__

Noah
Noah
发布时间:2026-10-15| 6人浏览过
原创

本文详解Python上下文管理器协议,重点解析__enter__和__exit__魔术方法。通过文件操作与pymysql数据库连接的实例,展示如何自定义类以支持with语句,实现资源自动获取与释放,包括游标关闭和连接断开。

前言

在实现上下文管理器协议时,核心涉及两个魔术方法:__enter__ 和 __exit__。

  • 在Python中,任何实现了上下文管理器协议的对象,均可使用 with 语句进行操作。
  • with 语句负责启动对象的上下文管理器流程。

上下文管理器协议的具体规范如下:

  • __enter__ 方法:进入该方法后,其返回值会被 as 子句后的变量接收。
  • __exit__ 方法:当 with 块内所有语句执行完毕后,自动调用该方法进行清理或异常处理。

下面通过一个简单的文件操作示例来演示上下文管理器协议的实际应用:

class MyOpen:
    # 实例化
    def __init__(self, filename, mode, encoding):
        self.filename = filename
        self.mode = mode
        self.encoding = encoding

    def __enter__(self):
        print("---enter---方法")
        # 执行文件打开操作
        self.f = open(self.filename, self.mode, encoding=self.encoding)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        :param exc_type: 异常类型
        :param exc_val: 异常信息
        :param exc_tb: 异常溯源对象
        :return:
        """
        print('----enter---')
        self.f.close()
with MyOpen('hr.txt', 'w', encoding='utf-8') as f:
    print(f.write('当前打开了文件,写入了数据:23323232'))

接下来,使用 pymysql 实现一个操作数据库的类,通过实现上下文管理器协议,确保在退出上下文时自动关闭游标并断开数据库连接。

版本1实现思路

# todo:版本1:
class mysql_db(object):
    #实例化属性
    def __init__(self):

第一步:建立数据库连接。

        self.cou = pymysql.connect(
            host= "数据库主机地址",  
            port= 端口,  
            user="登录数据库的账号",  
            password="登录数据库的密码", 
            database="数据库名称",  
            charset='utf8',     编码格式
            cursorclass=pymysql.cursors.DictCursor     将默认的元组格式转换成字典格式输出
        )  

第二步:创建数据库游标对象。

        self.cur = self.cou.cursor()
    def __enter__(self):
        return self.cur       返回cur对象
    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        :param exc_type: 异常类型
        :param exc_val: 异常信息
        :param exc_tb: 异常溯源对象
        :return:
        """
        #关闭游标
        self.cur.close()
       # 关闭数据库连接
        self.cou.close()
def Obtain_one_date():
    with mysql_db() as db:
        db.execute('select * from t_customer LIMIT 4')     使用execute方法进行查询语句
        content = db.fetchone()  返回一条数据的查询的结果
        print(content)

# 函数调用
Obtain_one_date()

版本2优化方案

sql = 'select * from t_customer LIMIT 4'
def mysql_db1(**kwargs):
    return pymysql.connect(host=kwargs.get('host', 'xxxx'),
                           user=kwargs.get("user",'xxxx'),
                           passwd=kwargs.get("passwd",'xxxx'),
                           database=kwargs.get("database",'xxxx'),
                           port=kwargs.get('port', xxxx),
                           charset=kwargs.get('charset', 'utf8'))

第一步:创建数据库连接对象。

cou = mysql_db1()

第二步:基于连接对象创建游标。

with cou.cursor() as cu:
    cu.execute(sql)      使用execute方法进行查询语句
    commt = cu.fetchone()     返回一条数据的查询的结果
    print(commt)

# 函数调用
mysql_db1()

至此,关于Python上下文管理器协议的实现介绍完毕。如需了解更多相关内容,可搜索本站历史文章或继续浏览后续文章,感谢支持!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。