from contextlib import closing

def init_db():
    with closing(connect_db()) as db:
        with app.open_resource('schema.sql') as f:
            db.cursor().executescript(f.read())
        db.commit()

这是来自 flask 教程第3步(http://flask.pocoo.org/docs/tutorial/dbinit/#tutorial-dbinit)。我对此并不奇怪,第4行。

我必须导入并使用“contextlib.closing()”方法吗?

当我通过语句了解到时,很多文章都说它会在如下所示的过程之后自动关闭文件。
with open('filename','w') as f:
    f.write(someString);

即使我不像下面那样使用contextlib.closing(),有什么区别?
它来自2.7.6版本,谢谢。
def init_db():
    with connect_db() as db:
        with app.open_resource('schema.sql') as f:
            db.cursor().executescript(f.read())
        db.commit()

最佳答案

是的,您应该使用context.closing();您自己的版本会完全不同。
with语句让上下文管理器知道何时输入和退出代码块。如果发生异常,则在退出时,上下文管理器还可以访问该异常。退出该块时,文件对象使用此对象自动关闭文件。

本教程中的connect_db()函数返回 sqlit3 connection object,实际上可以将其用作context manager但是connection.__exit__()方法不会关闭连接,它会在成功完成后提交事务,或者在出现异常时中止该事务。

另一方面,contextlib.closing()上下文管理器在连接上调用connection.close()方法。这是完全不同的东西。

因此,您的第二个片段可能有用,但功能有所不同。教程代码关闭连接,您的版本提交事务。您已经在调用db.commit(),因此如果没有引发异常,则该操作实际上是多余的。

您可以再次将该连接用作上下文管理器,以具有自动事务处理行为:

def init_db():
    with closing(connect_db()) as db:
        with app.open_resource('schema.sql') as f, db:
            db.cursor().executescript(f.read())

注意第二条, db行上的with,确保在块退出时调用db.__exit__()方法。

关于python - python 'with'语句,我应该使用contextlib.closing吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20793283/

10-10 11:47