什么是构造一个对象以打开多个(情境管理)资源,也与这些资源工作的最Python的方式?
我有打开多个管理资源,然后在类中的方法操作的一类。
例如,如果我不得不打开在同一时间到本地缓存数据库和Web服务器的连接(例如,检查缓存中的数据,然后再从服务器如果不出现拉)。
我已经能够拿出一些代码来管理使用yield语句的资源,但它似乎并不十分直观。在Python,有没有处理这个问题的一个规范的方法?
from contextlib import contextmanager
@contextmanager
def resource_A():
print('opening resource A...')
a = 'resource_A'
yield a
print('closing resource A...')
@contextmanager
def resource_B():
print('opening resource B...')
b = 'resource_B'
yield b
print('closing resource B...')
class ResourceManager(object):
def opened(self):
self.resources = self._resources()
self.a, self.b = next(self.resources)
def closed(self):
try:
next(self.resources)
except StopIteration:
del self.resources
del self.a
del self.b
def _resources(self):
with resource_A() as a, resource_B() as b:
yield a, b
def processing(self):
print('doing something with resource_A and resource_B...')
def __enter__(self):
self.opened()
return self
def __exit__(self, ex_type, ex_val, traceback):
self.closed()
>>> r = ResourceManager()
>>> r.opened()
opening resource A...
opening resource B...
>>> r.a
'resource_A'
>>> r.b
'resource_B'
>>> r.closed()
closing resource B...
closing resource A...
>>> with ResourceManager() as r:
... r.processing()
...
opening resource A...
opening resource B...
doing something with resource_A and resource_B...
closing resource B...
closing resource A...
上面的代码看起来做工精细,但它似乎并不十分直观。具体来说,产量在下一个成语似乎有点难以消化。
有没有更好的方法来打开,这将在Python类方法随后用于/关闭多个管理资源?
ExitStack
会让你的代码更容易__enter__
并明确__exit__
比next(...)
啄更具可读性opened
和closed
全文应该返回布尔不能称为属性,即r.opened -> True
。这是大多数人会从你的界面的期望。操作上另一方面,应拼写为动词,像open
和close
。简单的例子,与上述思路:
class ResourceManager(object):
def open(self):
self.stack = ExitStack()
self.a = self.stack.enter_context(resource_A())
self.b = self.stack.enter_context(resource_B())
def close(self):
self.stack.close()
def processing(self):
print('doing something with resource_A and resource_B...')
def __enter__(self):
self.open()
return self
def __exit__(self, ex_type, ex_val, traceback):
self.close()