如何覆盖 python 对象中的方法?

How to override method in python object?

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

我正在使用 psycopg2.connect() to create connections. The connection object 有一个 'close' 方法,我相信调用它来关闭连接。为了找到位置,我试图像这样覆盖 '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'。我为我创建的 classes 尝试了这种技术并且它有效。我认为这可能与在 C 中作为扩展模块实现的 connection class 有关。有什么方法可以修补 connection.close() 方法吗?当 connection.close() 被调用时,还有其他方法可以找到调用堆栈吗?我没有附加调试器的选项。但是我可以将消息打印到控制台进行调试。

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

与其修补对象,不如继承 Connection 并覆盖 close:

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

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

c = psycopg2.connect(connection_factory=MyConnection)