如何将弱变量转换为强变量?

2024-04-29 16:44:21 发布

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

在Python中有没有办法将弱变量转换为强变量

# utils.py

def connect_db():
    cnx = mysql.connector.connect(user="root", database="test_db")
    cursor = cnx.cursor()
    return cursor
# main.py

from utils import connect_db

def main():
    cursor = connect_db()
    cursor.execute("some commands")

我犯了这个错误

ReferenceError: weakly-referenced object no longer exists

Tags: pytestdbconnectormaindefconnectmysql
1条回答
网友
1楼 · 发布于 2024-04-29 16:44:21

首先,让我们看看为什么会发生错误。打开连接并将其绑定到函数本地名cnx。然后创建一个游标,该游标对连接的引用较弱。一旦返回游标,连接就不再具有强引用,它将被启动以进行垃圾收集。当您尝试执行查询时,连接已被垃圾回收

正如您所指出的,将光标与连接之间的引用设置为强引用将解决您眼前的问题。同时,API以这种方式设计也是有原因的。您不希望有太多的连接徘徊,这一切都是因为一些游标没有得到垃圾收集

相反,正确的答案是显式地处理连接,而不是将其隐藏在返回游标的函数中。除此之外,它应该在一个封闭的with块中完成,以便在出现错误时显式关闭。由于现有的实现似乎不支持上下文管理,因此必须显式地写出try-catch

例如,可以同时返回连接和光标:

def connect_db():
    cnx = mysql.connector.connect(user="root", database="test_db")
    cursor = cnx.cursor()
    return cnx, cursor

def main():
    cnx = None
    try:
        cnx, cursor = connect_db()
        cursor.execute("some commands")
    finally:
        if cnx is not None:
            cnx.close()

更优雅的解决方案可能是为数据库创建自己的上下文管理器,而不是返回两个单独的对象(类似于https://stackoverflow.com/a/67645694/2988730,但更封装):

class connect_db:
    def __enter__(self):
        self.cnx = mysql.connector.connect(user="root", database="test_db")
        self.cursor = self.cnx.cursor()
        return cursor

    def __exit__(self, *args):
        self.cursor.close()
        self.cnx.close()


def main():
    with connect_db() as cursor:
        cursor.execute("some commands")

相关问题 更多 >