构造对象以打开多个(上下文托管)资源并使用这些资源的最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的类方法中使用?
答案 0 :(得分:1)
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()