python - 如何在Python中使用上下文管理器

标签 python with-statement contextmanager

下面是一段假设的代码

with dbengine.connect(**details) as db:
    cur = db.exec(sql_string)
    results = cur.fetchall()
return results

在这种情况下,我希望当使用 block db.close() 进行选项卡out时,调用该 block 并将 db 标记为垃圾回收。

在工作中,我开始看到这段代码的出现。

with something() as myobj:
    logger.info('I got an obj!')
return myobj

我不知道你是否应该像java中的new关键字一样使用with。有人可以指导我任何好的文档来解释使用 with 时可以/不应该/不应该做什么吗?

P.S 日志消息实际上就是那么蹩脚:-)

最佳答案

with语句将contextmanager__enter__返回值绑定(bind)到的目标名称(as后面的名称)不仅仅限于 with 语句。与 for 循环变量一样,as 目标名称的作用域为当前函数或模块命名空间。当 with 套件结束时,该名称不会消失或被清除。

因此,with 语句的 return myobj outside 是完全合法的,尽管有些荒谬。 with 语句保证的是,当 block 完成时(即到达 block 的末尾,或者因为 continuebreakreturn 语句,或者因为引发了异常)。

也就是说,您最好将 return 移至 with 语句内:

with something() as myobj:
    logger.info('I got an obj!')
    return myobj

with dbengine.connect(**details) as db:
    cur = db.exec(sql_string)
    return cur.fetchall()

上下文管理器仍将被正确清理,但现在 return 语句看起来像是 with block 的逻辑部分。执行顺序不改变;调用 something().__exit__(),然后函数返回。

一如既往,Python documentation on the with syntax非常好。您还可以查看documentation on context managersoriginal proposal, PEP-343 .

关于python - 如何在Python中使用上下文管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16774714/

相关文章:

Python:根据现有列将列添加到 CSV 文件

python - 如果一次读取整个文件需要 with 语句?

vb.net - VB.NET 'With' 声明 - 接受还是避免?

ms-access - VBA - "With Statements"嵌套在 "IF Statements"内

python - Graphite 烯在上下文管理器中运行所有解析器

pycharm - 如何在PyCharm中正确注释ContextManager?

python - Python2.7 上下文管理器类中处理异常的正确方法

python TypeError 并非所有参数在字符串格式化期间都被转换

python - findChild 使用自定义小部件返回 None

python - 使用 numpy.genfromtxt 填充缺失值