Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用上下文管理器选择数据库或文件处理程序_Python_Python 3.x_Contextmanager - Fatal编程技术网

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))