为何SQLite连接与游标在with代码块外仍可正常使用?
问题描述
我的系统环境:
- Windows 10 x64
- Python版本 3.9.4
- 标准库集成的SQLite3模块
我知道数据库连接(DB connection)和游标(cursor)属于资源,所以可以用with语句。原本以为with代码块中打开的资源会在块外自动关闭(比如文件就是这样),但实际测试发现,在with代码块外仍然能访问并使用连接或游标,这是为什么?
测试代码如下:
import sqlite3 with sqlite3.connect('test.db') as conn: cur = conn.cursor() # some code here.... # Now we are outside with block but I can still use conn and cur cur.execute('''CREATE TABLE IF NOT EXISTS users (name TEST, surname TEXT) ''') cur2 = conn.cursor()
解答
这是因为SQLite3连接对象的with语句行为和你熟悉的文件对象不一样:
- 文件对象的
with块结束时,会直接调用close()方法关闭文件,所以块外无法再操作。 - 但SQLite3的连接对象使用
with时,只是自动处理事务:如果块内没有抛出异常,会自动提交事务;如果有异常,会自动回滚事务。它并不会在with块结束时关闭连接,连接仍然处于打开状态,所以你还能继续用它创建游标、执行SQL。
至于游标,它的生命周期依赖于连接对象——只要连接没关闭,游标就能继续使用。除非你显式调用cur.close()或者连接被关闭,否则游标不会失效。
如果想要在with块结束后关闭连接,需要手动调用conn.close(),或者把conn.close()放在with块的最后,依赖Python垃圾回收机制(当conn变量被销毁时连接会关闭)并不太可靠。
内容的提问来源于stack exchange,提问作者filograndipad2
相关产品推荐
相关产品推荐

