📅  最后修改于: 2020-05-05 05:17:23             🧑  作者: Mango
管理资源:在任何编程语言中,诸如文件操作或数据库连接之类的资源使用都很普遍。但是这些资源供应有限。因此,主要问题在于确保使用后释放这些资源。如果不释放它们,则将导致资源泄漏,并可能导致系统变慢或崩溃。如果用户具有自动设置和拆卸资源的机制,这将非常有帮助。在Python中,可以通过使用上下文管理器来实现,这有助于对资源的正确处理。执行文件操作的最常见方式是使用with关键字,如下所示:
# Python程序显示与with关键字一起使用
with open("test.txt") as f:
data = f.read()
让我们以文件管理为例。打开文件时,将使用文件描述符,这是一种有限的资源。一次只能打开一定数量的文件。下面的程序演示它。
file_descriptors = []
for x in range(100000):
file_descriptors.append(open('test.txt', 'w'))
输出:
Traceback (most recent call last):
File "context.py", line 3, in
OSError: [Errno 24] Too many open files: 'test.txt'
一条错误消息,指出打开了太多文件。上面的示例是文件描述符泄漏的情况。发生这种情况是因为打开的文件太多,并且它们没有关闭。程序员可能会忘记关闭打开的文件。
使用上下文管理器管理资源:
假设代码块引发异常,或者如果代码块具有包含多个返回路径的复杂算法,则在所有位置关闭文件将变得很麻烦。
通常,在使用其他语言时,使用文件try-except-finall y可以确保即使有异常也可以在使用后关闭文件资源。Python提供了一种简单的方法来管理资源:Context Managers:使用with关键字。上下文管理器可以使用类或函数(带有装饰器)来编写。
创建一个上下文管理器:
使用类创建上下文管理器时,用户需要确保该类具有以下方法:__ enter __()和__exit __()。__enter __()返回需要管理的资源,而__exit __()不返回任何内容,而是执行清理操作。
首先,让我们创建一个名为ContextManager的简单类,以了解使用类创建上下文管理器的基本结构,如下所示:
# Python程序创建上下文管理器
class ContextManager():
def __init__(self):
print('init method called')
def __enter__(self):
print('enter method called')
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
print('exit method called')
with ContextManager() as manager:
print('with statement block')
输出:
init method called
enter method called
with statement block
exit method called
在这种情况下,将创建一个ContextManager对象。这是在as关键字(即manager)之后分配给变量的。在运行上述程序时,将依次执行以下操作:
使用上下文管理器进行文件管理:
让我们应用以上概念创建一个有助于文件资源管理的类。FileManager类有助于打开文件,写入/读取内容然后关闭它。
# Python程序使用上下文管理器显示文件管理
class FileManager():
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, exc_traceback):
self.file.close()
# 加载文件
with FileManager('test.txt', 'w') as f:
f.write('Test')
print(f.closed)
输出:
True
使用上下文管理器和with语句进行文件管理:
在执行with块时,将依次执行以下操作:
使用上下文管理器进行数据库连接管理:
让我们创建一个简单的数据库连接管理系统。一次可以打开的数据库连接的数量也受到限制(就像文件描述符一样)。因此,上下文管理器有助于管理与数据库的连接,因为程序员可能会忘记关闭连接。
# Python程序显示了用于MongoDB的连接管理
from pymongo import MongoClient
class MongoDBConnectionManager():
def __init__(self, hostname, port):
self.hostname = hostname
self.port = port
self.connection = None
def __enter__(self):
self.connection = MongoClient(self.hostname, self.port)
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self.connection.close()
# 与本地主机连接
with MongoDBConnectionManager('localhost', '27017') as mongo:
collection = mongo.connection.SampleDb.test
data = collection.find({'_id': 1})
print(data.get('name'))
使用上下文管理器和with语句进行数据库连接管理:
在执行with块时,将依次执行以下操作: