【问题标题】:How to override method in python object?如何覆盖python对象中的方法?
【发布时间】:2021-10-16 19:46:43
【问题描述】:

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

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

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

【问题讨论】:

    标签: python sqlalchemy psycopg2


    【解决方案1】:

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

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

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

    c = psycopg2.connect(connection_factory=MyConnection)
    

    【讨论】:

    • 我也试过了。但是有一些奇怪的错误: sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) 异步连接尝试正在进行 当 sqlalchemy 尝试使用该更改创建连接时。当我使用实际的连接对象时,错误不存在。在那之后,我没有尝试进一步追求。我假设 psycopg2 有一些明确的检查导致它失败。
    • 对不起。当我得到错误时,我尝试了一些稍微不同的东西。我会试试这个,看看。谢谢。
    • 解决了我的问题!非常感谢@chepner。这几天我一直在为此苦苦挣扎。
    猜你喜欢
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2013-04-13
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    相关资源
    最近更新 更多