python-3.x - 类内引用的上下文管理
问题描述
__del__
在清理 Python 类时,这似乎是一个糟糕的选择,主要是因为并不总是保证会调用它。假设我有一个流程管理类,如下所示:
class ProcessCTL(object):
def __init__(self):
self._procs = {}
def __getitem__(self, key):
return self._procs[key]
def __setitem__(self, key, cls):
self._procs[key] = cls
def __iter__(self):
return iter(self._procs.items())
def __del__(self):
self.kill_all()
def start_all(self):
for _, cls in self:
cls.start()
def kill_all(self):
for _, cls in self:
cls.kill()
start
它只是保留了对另一个实现子进程的 Python 类的引用字典kill
。
然后ProcessCTL
可以在其他类中使用该类,如下所示:
class Foo(object):
def __init__(self):
self.pctl = ProcessCTL()
self.pctl['db'] = DBConnection()
self.pctl.start_all()
def do_work(self, stmt):
self.pctl['db'].execute(stmt)
return self.pctl['db'].fetchall()
但是,当Foo
被删除时,不能保证DBConnection.kill
会被调用。我可以添加另一个类似Foo.close
的方法轮流调用ProcessCTL.kill_all
,但我不想依赖开发人员调用close
,并且想自动处理事情。
其他选项包括类似的东西atexit
,但这里的问题再次是开发人员可能会选择以Foo
某种奇怪的方式使用,或者发送未被处理的信号atexit
等。
对其他对象的引用进行“类级别”上下文管理的最佳方法是什么,以便Foo
可以创建一个实例,并且一旦使用它,我保证ProcessCTL.kill_all
也会被调用?
我试过添加__enter__
和__exit__
方法ProcessCTL
,希望这样的事情是可能的:
class ProcessCTL(object):
def __init__(self):
self._procs = {}
def __getitem__(self, key):
return self._procs[key]
def __setitem__(self, key, cls):
self._procs[key] = cls
def __iter__(self):
return iter(self._procs.items())
def __del__(self):
self.kill_all()
def __enter__(self):
return self
def __exit__(self, t, v, e):
self.kill_all()
def start_all(self):
for _, cls in self:
cls.start()
def kill_all(self):
for _, cls in self:
cls.kill()
class Foo(object):
def __init__(self):
self.pctl = _get_pctl()
def _get_pctl():
with ProcessCTL() as pctl:
pctl['db'] = DBConnection()
pctl.start_all()
yield pctl
但yield
将始终返回 a generator
,而不是对已创建ProcessCTL
实例的引用。
解决方案
推荐阅读
- xgboost - 将训练数据拟合到 xgboost 时出现分段错误
- python - 如何更新 Piplock 文件?
- c++ - 用零初始化 std::chrono::time_point 变量
- scala - 对象的方法如何引用该对象的内部类?
- javascript - 在移动设备上关闭和打开 Chrome 浏览器后 Swiper 幻灯片调整大小
- node.js - Nodejs:在查询执行期间等待API响应
- html - 我如何应用这个 CSS 类
- java - 为什么浏览器实例在 Selenium 和 TestNG 中执行后没有关闭/退出?
- python - 是否有任何算法可以检测图中最远的两个节点?对不起,如果这个问题可能是微不足道的
- python-2.7 - 如何使用 Microsoft 图形 API 在 Onedrive 中公开文件