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

2024-09-29 19:21:35 发布

您现在位置:Python中文网/ 问答频道 /正文

首先让我承认这里已经有一个很好的讨论:How do I correctly clean up a Python object?

我正在努力提高一些代码的效率,这些代码目前是这样的:

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()

如您所见,这是正确的,但是每次都会不必要地打开和关闭数据库连接,我正在尝试改进这一点

应用程序使用上述代码的方式如下:

h = StuffHandler(db_credentials)
my_obj.set_stuff_handler(h)

我希望这个对象保持一个长寿命的连接,从原理上说,我认为它应该是这样工作的

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)

问题是:在Python中,如何正确地清理资源?这包括关闭连接,还包括添加缓冲区、刷新缓冲区等

根据被标记为正确且更新了很多的答案https://stackoverflow.com/a/865272/12595391,答案是:添加方法__enter____exit__,这样这个类就可以用作上下文。我想这意味着:

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)

但是我不想碰应用程序代码

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

谢谢你的帮助


Tags: 方法答案代码importselfdbdefas
1条回答
网友
1楼 · 发布于 2024-09-29 19:21:35

您可以尝试使用uu del_uuu,认为上下文管理器更好

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)
    def __del__():
        self.conn.close()

当一个对象被垃圾收集时调用它,What is the __del__ method, How to call it?

相关问题 更多 >

    热门问题