Python中15个让你代码更优雅的上下文管理器用法
https://img-blog.csdnimg.cn/img_convert/844205896b9696c0db48b484232690e4.jpeg文末赠免费佳构编程资料~~
本日,我们要探索的是Python中一个超级实用又每每被低估的特性——上下文管理器。这可不是普通的魔法,它能让你的代码更加整齐、安全,还能自动处理资源,就像变把戏一样。准备好,让我们一起揭开它的神秘面纱。
1. 自动打开和关闭文件
题目场景:每次操纵文件,都要手动打开和关闭,忘了close()可是大忌。
优雅解决方案:
with open('example.txt', 'r') as file:
content = file.read()
这段代码自动管理了文件句柄,无论是否发生非常,文件都会被正确关闭。魔法在于with关键字,后面跟着的就是上下文管理器对象。
2. 自定义上下文管理器
进阶玩法:自己定义上下文管理器,好比计时器。
class Timer:
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}秒")
with Timer():
time.sleep(2)
这里,__enter__和__exit__是关键方法,让类变成了上下文管理器。
3. 使用contextlib简化代码
简化法门:不想写类?contextlib.contextmanager来帮助。
from contextlib import contextmanager
@contextmanager
def simple_timer():
start = time.time()
yield
end = time.time()
print(f"耗时: {end - start}秒")
with simple_timer():
time.sleep(1)
yield像一个分界点,之前的是__enter__,之后的是__exit__。
4. 数据库毗连管理
实战案例:数据库操纵中,自动管理毗连和关闭。
from contextlib import closing
import sqlite3
with sqlite3.connect("my_database.db") as connection:
with closing(connection.cursor()) as cursor:
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
这里,closing也是一个上下文管理器,确保毗连在操纵完成后关闭。
5. 锁定资源制止并发冲突
并发安全:在多线程环境下,使用threading.Lock作为上下文管理器。
import threading
lock = threading.Lock()
with lock:
# 在这里进行需要保护的代码
print("我是安全的并发操作")
确保同一时间只有一个线程访问这段代码。
6. 自动重试机制
提升稳定性:使用上下文管理器实现自动重试逻辑。
from retrying import retry
@retry(stop_max_attempt_number=3)
def unreliable_function():
if not random.randint(0, 1):
raise Exception("Failed!")
else:
print("成功执行了!")
unreliable_function()
固然不是直接的上下文管理器示例,但通过装饰器实现了雷同的结果。
7. 临时改变配置或环境变量
环境控制:在特定范围内临时修改配置。
class TempConfig:
def __init__(self, key, value):
self.key, self.old_value = key, os.environ.get(key)
def __enter__(self):
os.environ = self.value
def __exit__(self, *args):
if self.old_value is None:
del os.environ
else:
os.environ = self.old_value
with TempConfig('DEBUG', 'True'):
print(os.environ['DEBUG'])# 输出: True
print(os.environ.get('DEBUG'))# 如果之前没设置,这里可能输出None
8. 自动整理临时文件
资源管理:生成并自动整理临时文件。
import tempfile
with tempfile.TemporaryFile() as temp_file:
temp_file.write(b"Hello, World!")
temp_file.seek(0)
print(temp_file.read().decode())
# 文件自动删除,无需显式调用temp_file.close()
临时文件在离开with块后自动消失。
9. 日志上下文管理
日志管理:根据差别的上下文调解日志级别。
class LogLevelManager:
def __init__(self, logger, level):
self.logger = logger
self.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)
with LogLevelManager(logger, logging.DEBUG):
logger.debug("这是调试信息")
如许可以在特定代码段内调解日志级别,而不影响全局设置。
10. 错误处理与回滚
事件管理:在数据库操纵中,确保要么全成功,要么全失败。
# 假设有一个数据库事务处理函数
def transaction_operation(db_connection):
try:
# 执行一系列数据库操作
db_connection.commit()
except Exception as e:
db_connection.rollback()
raise e
# 使用上下文管理器包装事务逻辑
with db_connection:
transaction_operation(db_connection)
这里假设db_connection是一个支持上下文管理的数据库毗连对象,自动处理提交和回滚。
高级用法和最佳实践
11. 上下文管理器的链式使用
高级本领:有时间,我们需要同时管理多个资源,这时可以链式使用多个上下文管理器。
with open('file.txt', 'w') as file, sqlite3.connect('database.db') as connection:
file.write("准备存储数据...")
cursor = connection.cursor()
cursor.execute("INSERT INTO table VALUES (?)", ('data',))
这段代码展示了如何同时管理文件和数据库毗连,确保两个资源都被妥善处理。
12. 上下文表达式
简洁编码:Python 3.7+引入了上下文表达式,使得单行上下文管理变得可能。
content = (open('example.txt', 'r').read())
固然这种方式简洁,但在处理可能抛出非常的情况时不如with语句清晰,不推荐用于复杂的资源管理。
13. 上下文管理器的替换方案 - 使用finally
了解替换方案:在没有上下文管理器的情况下,try...finally...是确保资源整理的经典方式。
file = open('file.txt', 'w')
try:
file.write("Hello, World!")
finally:
file.close()
但这不如上下文管理器优雅,且轻易忘记。
14. 第三方库中的上下文管理器
扩展知识:许多第三方库提供了自己的上下文管理器,如requests库中的相应对象自动关闭。
import requests
with requests.get('https://api.example.com/data') as response:
data = response.json()
这里,response对象在退出with块时自动关闭毗连。
15. 设计模式与上下文管理器
设计头脑:将上下文管理器应用于设计模式,如单例模式,确保资源的唯一实例。
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances = instance
return cls._instances
class Singleton(metaclass=SingletonMeta):
pass
# 使用时
singleton1 = Singleton()
singleton2 = Singleton()
assert singleton1 is singleton2
固然这个例子没有直接使用上下文管理器,但它展示了元类如何在更深条理上控制对象的创建,这与上下文管理器在资源控制上的理念相呼应。
结语
通过这些深入的探讨,你不但掌握了上下文管理器的底子和高级用法,还学会了如何将其融入更广泛的设计思想中。
好了,本日的分享就到这里了,我们下期见。如果本文对你有帮助,请点赞、转发、点个在看吧!
文末福利
请关注下方公众号并背景回复编程资料免费获取Python编程、人工智能、爬虫等100+本佳构电子书。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]