
python入门——with方法底层—上下文管理器&__enter__()和__exit__()方法
with语句用于上下文管理,它能够确保资源在使用完毕后得到正确的释放,无需手动处理清理工作。它简化了资源管理代码,并且提供了异常安全性。with广泛用于文件操作、锁操作、数据库连接等需要清理资源的场景,也可以通过实现和__exit__()方法自定义上下文管理器。
·
with方法
概述:
一个类只要实现了 __enter__ 和 __exit__ 方法,则这个类就是 上下文管理器类
该类的对象 = 上下文管理器对象
特点:
1. 上下文管理器对象, 可以结合 with语句 使用
2. 在with语句执行前, 会自动调用 __enter__()方法, 用于初始化某些 变量
3. 在with语句执行后, 会自动调用 __exit__() 方法, 用于清理某些资源
回顾:
with语法 之所以强大, 底层就是 上下文管理器 在支撑
在 Python 中,with
语句是一种简洁的上下文管理工具,主要用于简化资源管理(如文件、网络连接、锁等)。它可以确保即使出现异常,相关资源(如文件、锁等)也能正确关闭或释放,避免资源泄露。
1. with
语句的作用:
with
语句可以用于确保在代码块执行结束后,自动清理资源(如关闭文件、释放锁等)。- 当进入
with
块时,会自动调用上下文管理器的__enter__()
方法。 - 当退出
with
块时,无论是否发生异常,都会调用上下文管理器的__exit__()
方法来进行清理工作。
2. 常见的 with
语句应用场景:
2.1 文件操作
文件处理是 with
语句的一个经典用例。with
确保文件在使用完毕后自动关闭,而无需显式调用 file.close()
。
with open('example.txt', 'r') as file:
content = file.read()
# 在这里文件已经被自动关闭,即使在读取过程中发生异常
2.2 锁操作
with
语句可以用于处理多线程编程中的锁,确保锁在使用完毕后自动释放。
import threading
lock = threading.Lock()
def task():
with lock:
# 访问共享资源
print("正在处理共享资源")
# 在 with 块结束时锁会自动释放
2.3 数据库连接或网络连接
with
语句可以确保数据库连接在操作结束后自动关闭,避免连接泄露。
import sqlite3
with sqlite3.connect('database.db') as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM table_name')
# 数据库连接在此处会自动关闭
3. __enter__()
和 __exit__()
方法:
__enter__()
方法在进入with
块之前执行,并且可以返回一个对象,该对象会绑定到with
的as
子句中。__exit__()
方法在退出with
块时执行。即使在with
块中发生异常,__exit__()
仍然会被调用,它可以用来处理或抑制异常。
class Resource:
def __enter__(self):
print("资源已获取")
return self # 返回自己作为上下文管理对象
def __exit__(self, exc_type, exc_value, traceback):
print("资源已释放")
if exc_type:
print(f"异常类型: {exc_type}, 异常值: {exc_value}")
return True # 返回 True 表示抑制异常,不向外传播
with Resource() as res:
print("使用资源")
raise ValueError("出现异常")
4. 自定义上下文管理器
通过定义一个类并实现 __enter__()
和 __exit__()
方法,可以创建自定义的上下文管理器,从而使该类能与 with
一起使用。
# 定义 上下文管理器类
class MyWith:
def __init__(self, file_path, mode):
# 文件路径
self.file_path = file_path
# 打开模式
self.mode = mode
# 文件对象
self.file_obj = None
def __enter__(self):
print('__enter__')
# 获取文件对象
self.file_obj = open(self.file_path, self.mode, encoding='utf-8')
# 返回文件对象
# return self.file_obj
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 实现文件关闭操作
self.file_obj.close()
print('file close...')
# 静态方法 实现read_data函数
# @staticmethod
# def read_data(file_obj):
# print('reading the first 10 lines:')
# for i in range(10):
# line = file_obj.readline()
# if not line: # 如果文件行数少于 10 行,则提前停止
# break
# print(line.strip())
def read_data(self):
print('reading the first 10 lines:')
for i in range(10):
lines = self.file_obj.readline()
if not lines:
break
print(lines.strip())
# 在 main函数中测试调用
if __name__ == '__main__':
with MyWith('test', 'r') as mf:
MyWith.read_data(mf)
总结:
with
语句用于上下文管理,它能够确保资源在使用完毕后得到正确的释放,无需手动处理清理工作。- 它简化了资源管理代码,并且提供了异常安全性。
with
广泛用于文件操作、锁操作、数据库连接等需要清理资源的场景,也可以通过实现__enter__()
和__exit__()
方法自定义上下文管理器。
更多推荐
所有评论(0)