前言
大家在python学习中一定用到过with open关键字来读写的文件操作,也一定知道with帮我们做的获取/关闭句柄的操作,但是它的底层是怎么实现的呢?
__enter__和__exit__方法
我们知道类在生成时会有个self参数,这个参数代表的就是类对象本身。而在with关键字后边呢我们常用as来获取句柄:
with open("test.txt", "w+", encoding="utf8") as f:
result = f.read()
其实能通过as获取操作文件的句柄正是在__enter__方法中实现的,并在__exit__方法中释放句柄,在这里我们用pymysql连接来示范with关键字的底层实现:
import pymysql
class con:
def __init__(self, host, port, db, user, pwd):
self.conn = pymysql.connect(
host=host,
port=port,
user=user,
password=pwd,
database=db,
cursorclass=pymysql.cursors.DictCursor
)
self.cur = self.conn.cursor()
print("连接已建立")
def __str__(self):
return "pymysql上下文管理器"
def __enter__(self):
# 返回类对象本身
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.cur.close()
self.conn.close()
print("连接已关闭")
# print(exc_type, "异常")
# print(exc_val, "异常")
# print(exc_tb, "异常")
# 查询单条数据
def read_one(self, sql):
try:
self.cur.execute(sql)
res = self.cur.fetchone()
except Exception as e:
print(e)
return res
调用:
with con("localhost", 3306, "tornado", "root", "root") as db:
print("这是一个", db)
res = db.read_one(" select * from `ad` ")
print(res)
结果如下:
总结
如上所述,with帮我们做的就是生成和释放实例,除了文件操作、数据库连接还可以在事务、socket等场景使用。