1

下面是一段假设的代码

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

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

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

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

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

PS 日志消息实际上是那么蹩脚:-)

4

1 回答 1

2

with语句将 contextmanager__enter__返回值绑定的目标名称(之后的名称as)不仅仅局限于with语句。与for循环变量一样,as目标名称的范围在当前函数或模块命名空间中。with当套件结束时,该名称不会消失或以其他方式清除。

因此,即使有些荒谬,声明return myobj 之外with内容也是完全合法的。该with语句所保证的只是something().__exit__()当块完成时将调用该方法(通过到达块的末尾,或者因为continue, breakorreturn语句,或者因为引发了异常)。

也就是说,您最好将 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块的逻辑部分。执行顺序不变;something().__exit__()被调用,然后函数返回。

与往常一样,关于语法的Python 文档with非常出色。您还可以查看有关上下文管理器的文档原始提案 PEP-343

于 2013-05-27T14:05:48.863 回答