当前位置:首页 > 科技  > 软件

Python上下文管理,你真的了解吗?

来源: 责编: 时间:2023-12-11 09:28:54 392观看
导读在 Python 编程中,有效地管理资源和处理异常是至关重要的。上下文管理器作为一种强大的工具,提供了一种优雅的方式来管理资源,确保它们在使用完毕后能够被正确释放。通过结合 with 语句,上下文管理器使得资源的获取和释放

在 Python 编程中,有效地管理资源和处理异常是至关重要的。上下文管理器作为一种强大的工具,提供了一种优雅的方式来管理资源,确保它们在使用完毕后能够被正确释放。通过结合 with 语句,上下文管理器使得资源的获取和释放变得简单而可靠,同时也使得异常处理变得更加优雅和简洁。本文将深入探讨 Python 中的上下文管理器,介绍其概念、用法和实际应用,并提供丰富的代码示例,帮助读者更好地理解和运用这一强大的特性。wac28资讯网——每日最新资讯28at.com

当谈论 Python 中的上下文管理时,我们通常是指 with 语句和上下文管理器。上下文管理器可以让我们更方便地管理资源,比如文件、网络连接或者数据库连接,同时也可以确保资源在使用完毕后得到正确的清理和释放。在本文中,我将详细介绍上下文管理器的概念、用法和实例,并提供丰富的代码示例。wac28资讯网——每日最新资讯28at.com

wac28资讯网——每日最新资讯28at.com

一、什么是上下文管理器?

在 Python 中,上下文管理器是指实现了 __enter__ 和 __exit__ 方法的对象。当我们使用 with 语句时,会调用上下文管理器的 __enter__ 方法获取资源,然后在 with 代码块执行结束后,无论是正常结束还是出现异常,都会调用 __exit__ 方法来进行清理和释放资源。wac28资讯网——每日最新资讯28at.com

上下文管理器可以用于许多场景,比如文件操作、线程锁、数据库连接等,它们能够确保资源的正确管理和释放,避免出现资源泄漏等问题。wac28资讯网——每日最新资讯28at.com

一个上下文管理器的类,最起码要定义 __enter__ 和 exit 方法。 让我们来构造我们自己的开启文件的上下文管理器,并学习下基础知识。wac28资讯网——每日最新资讯28at.com

class File(object):    def __init__(self, file_name, method):        self.file_obj = open(file_name, method)    def __enter__(self):        return self.file_obj    def __exit__(self, type, value, traceback):        self.file_obj.close()

wac28资讯网——每日最新资讯28at.com

通过定义 __enter__ 和 __exit__ 方法,我们可以在with语句里使用它。我们来试试:wac28资讯网——每日最新资讯28at.com

with File('demo.txt', 'w') as opened_file:    opened_file.write('Hola!')

wac28资讯网——每日最新资讯28at.com

我们的 __exit__ 函数接受三个参数。这些参数对于每个上下文管理器类中的 __exit__ 方法都是必须的。我们来谈谈在底层都发生了什么。wac28资讯网——每日最新资讯28at.com

  • with 语句先暂存了 File 类的 __exit__ 方法。
  • 然后它调用 File 类的 __enter__ 方法。
  • __enter__ 方法打开文件并返回给 with 语句。
  • 打开的文件句柄被传递给 opened_file 参数。
  • 我们使用 .write() 来写文件。
  • with 语句调用之前暂存的 __exit__ 方法。
  • __exit__ 方法关闭了文件。

二、实现上下文管理器

我们也可以自定义上下文管理器,只需实现 __enter__ 和 __exit__ 方法即可。wac28资讯网——每日最新资讯28at.com

  1. 基础实现
python复制代码class MyContextManager:    def __enter__(self):        print('Entering the context')        # 返回需要被管理的资源        return self    def __exit__(self, exc_type, exc_value, traceback):        print('Exiting the context')        # 在退出上下文时进行清理工作# 使用自定义的上下文管理器with MyContextManager() as manager:    # 在这个代码块中使用 manager 管理的资源    pass

2. 嵌套使用

上下文管理器可以进行嵌套使用,这样可以方便地管理多个资源。上下文管理器的嵌套使用可以帮助我们方便地管理多个资源。这种嵌套使用可以确保资源的正确获取和释放,使代码更加清晰和易于维护。这里有一个示例,演示了如何嵌套使用多个上下文管理器:wac28资讯网——每日最新资讯28at.com

class DatabaseConnection:    def __enter__(self):        print('Opening database connection')        # 假设这里是连接数据库的代码        return self    def __exit__(self, exc_type, exc_value, traceback):        print('Closing database connection')        # 假设这里是关闭数据库连接的代码class FileOperation:    def __enter__(self):        print('Opening file')        # 假设这里是打开文件的代码        return self    def __exit__(self, exc_type, exc_value, traceback):        print('Closing file')        # 假设这里是关闭文件的代码# 嵌套使用上下文管理器with DatabaseConnection() as db_connection:    with FileOperation() as file:        # 执行需要同时使用数据库连接和文件的操作        pass

wac28资讯网——每日最新资讯28at.com

在这个示例中,我们嵌套使用了 `DatabaseConnection` 和 `FileOperation` 两个上下文管理器,这样可以确保在操作完成后,数据库连接和文件都能被正确地关闭。wac28资讯网——每日最新资讯28at.com

嵌套使用上下文管理器使得我们能够更加灵活地管理多个资源,确保资源的获取和释放都能得到正确处理。这种方式使得代码的可读性更强,同时也降低了出错的可能性。wac28资讯网——每日最新资讯28at.com

希望这个示例能够帮助您更好地理解上下文管理器的嵌套使用。wac28资讯网——每日最新资讯28at.com

三、上下文管理器的应用

wac28资讯网——每日最新资讯28at.com

1. 文件操作

使用 with 语句管理文件资源wac28资讯网——每日最新资讯28at.com

with open('example.txt', 'r') as f:    for line in f:        print(line)# 文件在 with 代码块结束后自动关闭

wac28资讯网——每日最新资讯28at.com

2. 线程锁

wac28资讯网——每日最新资讯28at.com

import threadinglock = threading.Lock()with lock:    # 执行需要进行线程同步的操作    pass# 线程锁在 with 代码块结束后自动释放

3. 数据库连接

import pymysqlclass DBConnection:    def __enter__(self):        self.conn = pymysql.connect(host='localhost', user='user', password='password', db='test_db')        self.cursor = self.conn.cursor()        return self.cursor    def __exit__(self, exc_type, exc_value, traceback):        self.cursor.close()        self.conn.close()with DBConnection() as cursor:    cursor.execute('SELECT * FROM example_table')    # 执行数据库操作# 数据库连接在 with 代码块结束后自动关闭

4. 异常处理

我们还没有谈到 __exit__ 方法的这三个参数:type,value 和 traceback。 在第4步和第6步之间,如果发生异常,Python 会将异常的 type,value 和 traceback 传递给 __exit__ 方法。 它让 __exit__ 方法来决定如何关闭文件以及是否需要其他步骤。在我们的案例中,我们并没有注意它们。wac28资讯网——每日最新资讯28at.com

那如果我们的文件对象抛出一个异常呢?万一我们尝试访问文件对象的一个不支持的方法。举个例子:wac28资讯网——每日最新资讯28at.com

with File('demo.txt', 'w') as opened_file:    opened_file.undefined_function('Hola!')

我们来列一下,当异常发生时,with 语句会采取哪些步骤:wac28资讯网——每日最新资讯28at.com

  • 它把异常的 type,value 和 traceback 传递给 __exit__方法。
  • 它让 __exit__ 方法来处理异常。
  • 如果 __exit__ 返回的是 True,那么这个异常就被优雅地处理了。
  • 如果 __exit__ 返回的是 True 以外的任何东西,那么这个异常将被 with 语句抛出。

在我们的案例中,__exit__ 方法返回的是 None (如果没有 return 语句那么方法会返回 None)。因此,with 语句抛出了那个异常。wac28资讯网——每日最新资讯28at.com

Traceback (most recent call last):File "<stdin>", line 2, in <module>AttributeError: 'file' object has no attribute 'undefined_function'

wac28资讯网——每日最新资讯28at.com

我们尝试下在 exit 方法中处理异常:wac28资讯网——每日最新资讯28at.com

class File(object):    def __init__(self, file_name, method):        self.file_obj = open(file_name, method)    def __enter__(self):        return self.file_obj    def __exit__(self, type, value, traceback):        print("Exception has been handled")        self.file_obj.close()        return Truewith File('demo.txt', 'w') as opened_file:    opened_file.undefined_function()# Output: Exception has been handled

wac28资讯网——每日最新资讯28at.com

我们的 `__exit__` 方法返回了 `True`,因此没有异常会被 `with` 语句抛出。wac28资讯网——每日最新资讯28at.com

这还不是实现上下文管理器的唯一方式。还有一种方式,我们会在下一节中一起看看。wac28资讯网——每日最新资讯28at.com

wac28资讯网——每日最新资讯28at.com

上下文管理器在异常处理方面也非常有用,当 with 代码块中出现异常时,上下文管理器的 __exit__ 方法会被调用,这样我们可以在 exit 方法中处理异常并进行资源的释放和清理。wac28资讯网——每日最新资讯28at.com

class MyContextManager:    def __enter__(self):        print('Entering the context')        return self    def __exit__(self, exc_type, exc_value, traceback):        print('Exiting the context')        if exc_type is not None:            print(f'An error occurred: {exc_value}')        # 在退出上下文时进行清理工作# 使用自定义的上下文管理器处理异常with MyContextManager() as manager:    # 在这个代码块中可能会出现异常    raise ValueError('Something went wrong')

wac28资讯网——每日最新资讯28at.com

总结

上下文管理器作为 Python 中极为重要的概念之一,为资源管理和异常处理提供了一种优雅而可靠的解决方案。通过定义自己的上下文管理器,我们可以轻松地扩展其应用范围,实现更多自定义的资源管理和清理逻辑。同时,上下文管理器的嵌套使用可以帮助我们更好地处理多个资源的管理,使得代码的结构更加清晰和可维护。wac28资讯网——每日最新资讯28at.com

通过本文的学习,读者可以更深入地理解上下文管理器的原理和用法,为编写更加健壮和可靠的 Python 代码打下坚实的基础。希望读者能够充分利用上下文管理器这一强大工具,提高自己的编程效率和代码质量。wac28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-41718-0.htmlPython上下文管理,你真的了解吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 数据加密难做?试试这个库

下一篇: 八个大幅提升开发效率的VS Code插件

标签:
  • 热门焦点
  • 5月iOS设备性能榜:M1 M2依旧是榜单前五

    和上个月一样,没有新品发布的iOS设备性能榜的上榜设备并没有什么更替,仅仅只有跑分变化而产生的排名变动,刚刚开始的苹果WWDC2023,推出的产品也依旧是新款Mac Pro、新款Mac Stu
  • 帅气纯真少年!日本最帅初中生选美冠军出炉

    日本第一帅哥初一生选美大赛冠军现已正式出炉,冠军是来自千叶县的宗田悠良。日本一直热衷于各种选美大赛,从&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • 超闭合精工铰链 彻底消灭缝隙 三星Galaxy Z Flip5与Galaxy Z Fold5发布

    2023年7月26日,三星电子正式发布了Galaxy Z Flip5与Galaxy Z Fold5。三星新一代折叠屏手机采用超闭合精工铰链,让折叠后的缝隙不再可见。同时,配合处
  • OPPO K11评测:旗舰级IMX890加持 2000元档最强影像手机

    【Techweb评测】中端机型用户群体巨大,占了中国目前手机市场的大头,一直以来都是各手机品牌的“必争之地”,其中OPPO K系列机型一直以来都以高品质、
  • OPPO K11搭载长寿版100W超级闪充:26分钟充满100%

    据此前官方宣布,OPPO将于7月25日也就是今天下午14:30举办新品发布会,届时全新的OPPO K11将正式与大家见面,将主打旗舰影像,和同档位竞品相比,其最大的卖
  • 苹果140W USB-C充电器:采用氮化镓技术

    据10 月 30 日 9to5 Mac 消息报道,当苹果推出新的 MacBook Pro 2021 时,该公司还推出了新的 140W USB-C 充电器,附赠在 MacBook Pro 16 英寸机型的盒子里,也支
Top