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

时间:2013-05-27 13:51:22

标签: python with-statement contextmanager

以下是一段假设的代码

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

在这种情况下,我希望当使用块标记 out 时,调用db.close()并将db标记为垃圾回收。

在工作中,我已经开始看到此代码了。

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

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

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

1 个答案:

答案 0 :(得分:2)

with语句绑定contextmanager __enter__返回值as之后的名称)的目标名称不限于{{1声明。与with循环变量类似,for目标名称在当前函数或模块名称空间中作用域。当as套件结束时,名称不会消失或以其他方式清除。

因此,with声明之外的return myobj 是完全合法的,如果有些荒谬的话。 with语句保证的所有内容都是在块完成时调用with方法(通过到达块的末尾,或者因为something().__exit__(),{{ 1}}或continue语句,或者因为引发了异常)。

那就是说,只需移动里面的 break语句就可以了。

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,然后函数返回。

与往常一样,Python documentation on the with syntax非常出色。您还可以查看documentation on context managersoriginal proposal, PEP-343