su7*_*u7k 17 python with-statement contextmanager
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()
Run Code Online (Sandbox Code Playgroud)
这是来自烧瓶教程第3步(http://flask.pocoo.org/docs/tutorial/dbinit/#tutorial-dbinit).我对第4行感到好奇.
我必须导入并使用'contextlib.closing()'方法吗?
当我用语句学习时,很多文章说它会在下面的过程之后自动关闭文件.(与Last:thing.close()相同)
with open('filename','w') as f:
f.write(someString);
Run Code Online (Sandbox Code Playgroud)
即使我不使用下面的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()
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 19
是的,你应该使用context.closing(); 你自己的版本完全不同.
该with语句允许上下文管理器知道何时输入和退出代码块; 退出时,如果发生异常,则还可以访问上下文管理器.文件对象使用此选项在退出块时自动关闭文件.
本connect_db()教程中的函数返回一个sqlit3连接对象,该对象确实可以用作上下文管理器.但是,该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())
Run Code Online (Sandbox Code Playgroud)
请注意, db第二with行,确保db.__exit__()在块退出时调用该方法.
该语句所做的唯一事情是在进入块之前with调用方法,在退出块之前调用方法。如果未定义这些方法,则该语句将无法按您的预期工作。我不知道 的返回类型是什么,但我猜它可能是来自不同第三方库的许多不同的东西。因此,您的代码可能会在许多(所有?)情况下工作,但您永远不知道.__enter____exit__withconnect_dbclosingconnect_db
| 归档时间: |
|
| 查看次数: |
7441 次 |
| 最近记录: |