在对象破坏时清理内部pysqlite连接 [英] Cleaning up an internal pysqlite connection on object destruction

查看:94
本文介绍了在对象破坏时清理内部pysqlite连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有内部数据库连接的对象,该对象在整个生命周期内都处于活动状态。在程序运行结束时,必须提交并关闭连接。到目前为止,我已经使用了显式的 close 方法,但这有点麻烦,尤其是当调用代码中可能发生异常时。

I have an object with an internal database connection that's active throughout its lifetime. At the end of the program's run, the connection has to be committed and closed. So far I've used an explicit close method, but this is somewhat cumbersome, especially when exceptions can happen in the calling code.

我正在考虑使用 __ del __ 方法进行结算,但是在线阅读后,我有些担心。这是有效的使用模式吗?我可以确定内部资源将在 __ del __ 中正确释放吗?

I'm considering using the __del__ method for closing, but after some reading online I have concerns. Is this a valid usage pattern? Can I be sure that the internal resources will be freed in __del__ correctly?

此讨论提出了类似的问题,但没有找到满意的答案。我不想使用显式的 close 方法,并且不能将一起使用,因为我的对象并不是简单地用作开放式关闭,而是保留为另一个更大的对象的成员,该对象在GUI中运行时会使用它。

This discussion raised a similar question but found no satisfactory answer. I don't want to have an explicit close method, and using with isn't an option, because my object isn't used as simply as open-play-close, but is kept as a member of another, larger object, that uses it while running in a GUI.

C ++有完美的析构函数,可以安全释放资源,因此我可以想象Python也达成了共识。由于某些原因,似乎并非如此,社区中的许多人发誓要反对 __ del __ 。那么,有什么选择呢?

C++ has perfectly working destructors where one can free resources safely, so I would imagine Python has something agreed-upon too. For some reason it seems not to be the case, and many in the community vow against __del__. What's the alternative, then?

推荐答案

您可以制作一个连接模块,因为模块在整个应用程序中都保留相同的对象,并且注册一个函数以使用 atexit 模块

You can make a connection module, since modules keep the same object in the whole application, and register a function to close it with the atexit module

# db.py:
import sqlite3
import atexit

con = None

def get_connection():
    global con
    if not con:
        con = sqlite3.connect('somedb.sqlite')
    atexit.register(close_connection, con)
    return con

def close_connection(some_con):
    some_con.commit()
    some_con.close()

# your_program.py
import db
con = db.get_connection()
cur = con.cursor()
cur.execute("SELECT ...")

此建议基于以下假设:应用程序中的连接似乎是单个连接一个mod的实例(单例) ule global提供的很好。

This sugestion is based on the assumption that the connection in your application seems like a single instance (singleton) which a module global provides well.

如果不是这种情况,则可以使用析构函数。

If that's not the case, then you can use a destructor.

但是析构函数不要使用垃圾回收器和循环引用(必须在调用析构函数之前自行删除循环引用),如果不是这种情况(需要多个连接),则可以使用析构函数。只是不要保留循环引用,否则您将不得不自己破坏它们。

However destructors don't go well with garbage collectors and circular references (you must remove the circular reference yourself before the destructor is called) and if that's not the case (you need multiple connections) then you can go for a destructor. Just don't keep circular references around or you'll have to break them yourself.

此外,您对C ++的说法是错误的。如果您在C ++中使用析构函数,则在定义对象的块完成时(例如python的 with )或在使用 delete 时调用它们。 code>关键字(用于取消分配使用 new 创建的对象)。除此之外,您必须使用不是析构函数的显式 close()。因此,就像python一样-python甚至更出色,因为它具有垃圾收集器。

Also, what you said about C++ is wrong. If you use destructors in C++ they are called either when the block that defines the object finishes (like python's with) or when you use the delete keyword (that deallocates an object created with new). Outside that you must use an explicit close() that is not the destructor. So it is just like python - python is even "better" because it has a garbage collector.

这篇关于在对象破坏时清理内部pysqlite连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆