Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何确保类实例清理资源_Python_Database_Code Cleanup - Fatal编程技术网

Python:如何确保类实例清理资源

Python:如何确保类实例清理资源,python,database,code-cleanup,Python,Database,Code Cleanup,首先,让我承认,这里已经存在一个良好的讨论: 我试图提高一些代码的效率,这些代码目前大致如下: import psycopg2 class StuffHandler: def __init__(self, db_credentials): self.db_credentials = db_credentials def handle(self, stuff): try: with psycopg2.connect(self

首先,让我承认,这里已经存在一个良好的讨论:

我试图提高一些代码的效率,这些代码目前大致如下:

import psycopg2

class StuffHandler:
    def __init__(self, db_credentials):
        self.db_credentials = db_credentials
    def handle(self, stuff):
        try:
            with psycopg2.connect(self.db_credentials) as conn:
                with conn.cursor() as cursor:
                    cursor.execute( < write stuff to database > )
        except psycopg2.DataError as e:
            logger.error(e)
        finally:
            conn.close()
我希望这个对象保持一个长寿命的连接,从原理上说,我认为它应该是这样工作的

import psycopg2

class Handler:
    def __init__(self, db_credentials):
        self.conn = psycopg2.connect(db_credentials)
    def handle(self, stuff):
        # TODO: check that connection is still alive, but those are
        # details don't matter for this discussion
        try:
            with self.conn.cursor() as cursor:
                cursor.execute( < write stuff to database > )
        except psycopg2.DataError as e:
            logger.error(e)
所以现在我的问题是:如果我不想使用上下文怎么办?如果我不想做呢

with StuffHandler(db_credentials) as h:
    my_obj.set_stuff_handler(h)
但是我不想碰应用程序代码

在上面提到的问题中,这个答案中描述了另一种选择:他们建议使用
atexit.register()
注册清理方法。这不是更适合我的情况吗?这种方法的缺点是什么?评论人@hlongmore似乎提到了一个缺点,但我真的不明白他的意思


谢谢您的帮助。

您可以尝试使用_udel_uuu,但最好使用上下文管理器

导入psycopg2
类处理程序:
定义初始化(自我、数据库凭据):
self.conn=psycopg2.connect(db_凭据)
def手柄(自身、物料):
#TODO:检查连接是否仍处于活动状态,但这些连接是活动的
#细节对这次讨论无关紧要
尝试:
使用self.conn.cursor()作为光标:
cursor.execute()
除psycopg2.DataError外,错误为e:
记录器错误(e)
def _del__():
self.conn.close()

它在对象被垃圾收集时被调用,

所描述的缺点是,由于您正在注册一个实例以退出,因此该实例永远是垃圾收集的禁区。如果你只有一个例子,那很好。如果您动态地创建它们(并希望在退出时清理所有这些对象),那么如果您的应用程序是长期存在的,您可能会耗尽资源,或者快速创建这样的对象。那么,考虑到您提供的两个链接,还有什么不清楚的地方吗?是的:那么我如何正确处理所有四种情况:A)程序退出,B)对象被垃圾收集,C)对象的
\u del\u
被调用,D)解释器崩溃?没有上下文?所有这一切(除了解释器崩溃,该场景没有解决方案)都涉及到
weakref.finalize
。感谢您的回复,但您提供的链接中的前3个答案明确建议不要这样做:例如。“由于您无法保证它的执行,因此不应将需要运行的代码放入_del__;()-相反,此代码属于try块的finally子句或with语句中的上下文管理器。”同样,此人建议使用上下文,但我不想更改应用程序代码。
def __enter__(self):
    return self
def __exit__(exc_type, exc_value, traceback):
    self.conn.close()
with StuffHandler(db_credentials) as h:
    my_obj.set_stuff_handler(h)