Python 使用上下文管理器选择数据库或文件处理程序
我希望能够使用上下文管理器打开Python 使用上下文管理器选择数据库或文件处理程序,python,python-3.x,contextmanager,Python,Python 3.x,Contextmanager,我希望能够使用上下文管理器打开FileHandler或DBHandler,具体取决于参数。这两个类本身就是上下文管理器。我可以想出下面的代码,并想知道是否有更好的方法来做到这一点(请忽略任何缺失的函数) with语句不需要上下文管理器类型的可调用表达式–任何计算结果为上下文管理器的表达式都有效。这允许函数调用、条件表达式以及直接名称引用提供上下文管理器 您几乎可以删除所有间接操作,并直接选择适当的上下文管理器: class DBHandler: def __init__(self, na
FileHandler
或DBHandler
,具体取决于参数。这两个类本身就是上下文管理器。我可以想出下面的代码,并想知道是否有更好的方法来做到这一点(请忽略任何缺失的函数)
with
语句不需要上下文管理器类型的可调用表达式–任何计算结果为上下文管理器的表达式都有效。这允许函数调用、条件表达式以及直接名称引用提供上下文管理器
您几乎可以删除所有间接操作,并直接选择适当的上下文管理器:
class DBHandler:
def __init__(self, name):
self._db = some_db_api.open(name)
def write(self, val):
self._db.execute(val)
def __enter__(self):
return self
def __exit__(self, *exc):
# make a commit of no error occurred, rollback otherwise
if exc[0] is None:
self._db.commit()
else:
self._db.rollback()
context = open(name) if output_mode == 'f' else DBHandler(name)
with context as resource:
for i in range(5):
resource.write(str(i))
原则上,
。。。如果。。。否则…
也可以用语句内联到。为了便于阅读,它是分开的。为什么一开始就有这些间接的内容<代码>获取资源
除了调用未定义的资源。回滚
之外,似乎没有任何作用。为什么不直接使用FileHandler(name)
而不是get\u resource('file',name)
。您还可以在基类中定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,这意味着它们应该已经能够充当内容管理器。要么完全使用get\u resource
作为上下文管理器,并删除\uuuu enter\uuuu
/\uuuu exit\uuu
,要么删除get\u resource
并将适当的退出逻辑放在\uu exit\uu
处理程序中。是的,我同意,get_资源是一个不必要的间接方法,我认为工厂方法仍然有效,特别是当处理程序类的数量增加时。如果字符串参数与任何有效资源不匹配,我也会引发一个错误。感谢您的解释。我遗漏了这一关键信息:“with语句不需要上下文管理器类型的callable”
class DBHandler:
def __init__(self, name):
self._db = some_db_api.open(name)
def write(self, val):
self._db.execute(val)
def __enter__(self):
return self
def __exit__(self, *exc):
# make a commit of no error occurred, rollback otherwise
if exc[0] is None:
self._db.commit()
else:
self._db.rollback()
context = open(name) if output_mode == 'f' else DBHandler(name)
with context as resource:
for i in range(5):
resource.write(str(i))