找回密码
 会员注册
查看: 36|回复: 0

Python中15个让你代码更优雅的上下文管理器用法

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71086
发表于 2024-9-5 22:37:50 | 显示全部楼层 |阅读模式
文末赠免费精品编程资料~~今天,我们要探索的是Python中一个超级实用又往往被低估的特性——上下文管理器。这可不是普通的魔法,它能让你的代码更加整洁、安全,还能自动处理资源,就像变魔术一样。准备好,让我们一起揭开它的神秘面纱。1.自动打开和关闭文件问题场景:每次操作文件,都要手动打开和关闭,忘了close()可是大忌。优雅解决方案:withopen('example.txt','r')asfile:content=file.read()12这段代码自动管理了文件句柄,无论是否发生异常,文件都会被正确关闭。魔法在于with关键字,后面跟着的就是上下文管理器对象。2.自定义上下文管理器进阶玩法:自己定义上下文管理器,比如计时器。classTimer:def__enter__(self):self.start=time.time()def__exit__(self,exc_type,exc_val,exc_tb):self.end=time.time()print(f"操作耗时:{self.end-self.start}秒")withTimer():time.sleep(2)12345678910这里,__enter__和__exit__是关键方法,让类变成了上下文管理器。3.使用contextlib简化代码简化秘诀:不想写类?contextlib.contextmanager来帮忙。fromcontextlibimportcontextmanager@contextmanagerdefsimple_timer():start=time.time()yieldend=time.time()print(f"耗时:{end-start}秒")withsimple_timer():time.sleep(1)1234567891011yield像一个分界点,之前的是__enter__,之后的是__exit__。4.数据库连接管理实战案例:数据库操作中,自动管理连接和关闭。fromcontextlibimportclosingimportsqlite3withsqlite3.connect("my_database.db")asconnection:withclosing(connection.cursor())ascursor:cursor.execute("SELECT*FROMusers")print(cursor.fetchall())1234567这里,closing也是一个上下文管理器,确保连接在操作完成后关闭。5.锁定资源避免并发冲突并发安全:在多线程环境下,使用threading.Lock作为上下文管理器。importthreadinglock=threading.Lock()withlock:#在这里进行需要保护的代码print("我是安全的并发操作")1234567确保同一时间只有一个线程访问这段代码。6.自动重试机制提升稳定性:利用上下文管理器实现自动重试逻辑。fromretryingimportretry@retry(stop_max_attempt_number=3)defunreliable_function():ifnotrandom.randint(0,1):raiseException("Failed!")else:print("成功执行了!")unreliable_function()12345678910虽然不是直接的上下文管理器示例,但通过装饰器实现了类似的效果。7.临时改变配置或环境变量环境控制:在特定范围内临时修改配置。classTempConfig:def__init__(self,key,value):self.key,self.old_value=key,os.environ.get(key)def__enter__(self)s.environ[self.key]=self.valuedef__exit__(self,*args):ifself.old_valueisNone:delos.environ[self.key]elses.environ[self.key]=self.old_valuewithTempConfig('DEBUG','True'):print(os.environ['DEBUG'])#输出:Trueprint(os.environ.get('DEBUG'))#如果之前没设置,这里可能输出None123456789101112131415168.自动清理临时文件资源管理:生成并自动清理临时文件。importtempfilewithtempfile.TemporaryFile()astemp_file:temp_file.write(b"Hello,World!")temp_file.seek(0)print(temp_file.read().decode())#文件自动删除,无需显式调用temp_file.close()1234567临时文件在离开with块后自动消失。9.日志上下文管理日志管理:根据不同的上下文调整日志级别。classLogLevelManager:def__init__(self,logger,level):self.logger=loggerself.prev_level=logger.getEffectiveLevel()def__enter__(self):self.logger.setLevel(level)def__exit__(self,*args):self.logger.setLevel(self.prev_level)logger=logging.getLogger(__name__)logger.setLevel(logging.INFO)withLogLevelManager(logger,logging.DEBUG):logger.debug("这是调试信息")12345678910111213141516这样可以在特定代码段内调整日志级别,而不影响全局设置。10.错误处理与回滚事务管理:在数据库操作中,确保要么全成功,要么全失败。#假设有一个数据库事务处理函数deftransaction_operation(db_connection):try:#执行一系列数据库操作db_connection.commit()exceptExceptionase:db_connection.rollback()raisee#使用上下文管理器包装事务逻辑withdb_connection:transaction_operation(db_connection)123456789101112这里假设db_connection是一个支持上下文管理的数据库连接对象,自动处理提交和回滚。高级用法和最佳实践11.上下文管理器的链式使用高级技巧:有时候,我们需要同时管理多个资源,这时可以链式使用多个上下文管理器。withopen('file.txt','w')asfile,sqlite3.connect('database.db')asconnection:file.write("准备存储数据...")cursor=connection.cursor()cursor.execute("INSERTINTOtableVALUES(?)",('data',))1234这段代码展示了如何同时管理文件和数据库连接,确保两个资源都被妥善处理。12.上下文表达式简洁编码:Python3.7+引入了上下文表达式,使得单行上下文管理变得可能。content=(open('example.txt','r').read())1虽然这种方式简洁,但在处理可能抛出异常的情况时不如with语句清晰,不推荐用于复杂的资源管理。13.上下文管理器的替代方案-使用finally了解替代方案:在没有上下文管理器的情况下,try...finally...是确保资源清理的经典方式。file=open('file.txt','w')try:file.write("Hello,World!")finally:file.close()12345但这不如上下文管理器优雅,且容易忘记。14.第三方库中的上下文管理器扩展知识:许多第三方库提供了自己的上下文管理器,如requests库中的响应对象自动关闭。importrequestswithrequests.get('https://api.example.com/data')asresponse:data=response.json()1234这里,response对象在退出with块时自动关闭连接。15.设计模式与上下文管理器设计思维:将上下文管理器应用于设计模式,如单例模式,确保资源的唯一实例。classSingletonMeta(type):_instances={}def__call__(cls,*args,**kwargs):ifclsnotincls._instances:instance=super().__call__(*args,**kwargs)cls._instances[cls]=instancereturncls._instances[cls]classSingleton(metaclass=SingletonMeta):pass#使用时singleton1=Singleton()singleton2=Singleton()assertsingleton1issingleton212345678910111213141516虽然这个例子没有直接使用上下文管理器,但它展示了元类如何在更深层次上控制对象的创建,这与上下文管理器在资源控制上的理念相呼应。结语通过这些深入的探讨,你不仅掌握了上下文管理器的基础和高级用法,还学会了如何将其融入更广泛的设计思想中。好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请点赞、转发、点个在看吧!文末福利请关注下方公众号并后台回复编程资料免费获取Python编程、人工智能、爬虫等100+本精品电子书。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-9 05:58 , Processed in 1.152184 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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