首页 > 解决方案 > 如何覆盖python对象中的方法?

问题描述

我在我的多线程应用程序中使用 sqlalchemy 和基于 postgres/psycopg2 的连接池。我发现数据库连接在某些代码路径中正在关闭。我正在尝试确定代码中发生这种情况的位置。

我正在使用psycopg2.connect()创建连接。连接对象有一个“关闭”方法,我相信它被称为关闭连接。为了找到位置,我试图像这样覆盖“close()”函数:

def newclose(self):
    #print stack
    self.oldclose()

c = psycopg2.connect(...)
c.oldclose = c.close
c.close = types.MethodType(newclose, c)

但是,我收到错误AttributeError: 'psycopg2.extensions.connection' object has no attribute 'oldclose'。我为我创建的类尝试了这种技术并且它有效。我认为这可能与在 C 中作为扩展模块实现的连接类有关。有什么方法可以修补 connection.close() 方法吗?当 connection.close() 被调用时,有没有其他方法可以找到调用堆栈?我没有附加调试器的选项。但我可以将消息打印到控制台进行调试。

甚至替换“关闭”方法的代码也失败了(单独调用时)-AttributeError:“psycopg2.extensions.connection”对象属性“关闭”是只读的

标签: pythonsqlalchemypsycopg2

解决方案


而不是修补对象,您应该继承Connection和覆盖close

class MyConnection(psycopg2.extensions.connection):
    def close(self):
        # print stack
        super().close()

然后你可以告诉connect使用你的自定义子类。

c = psycopg2.connect(connection_factory=MyConnection)

推荐阅读