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

How to convert a weak variable to strong one?

有什么方法可以在 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

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

正如您所指出的,使从游标到连接的引用成为强引用将解决您眼前的问题。同时,API这样设计也是有原因的。您不希望有太多的连接徘徊,这都是因为一些游标没有得到垃圾收集。

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

例如,您可以 return 连接和光标:

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

一个更优雅的解决方案可能是为数据库创建您自己的上下文管理器,而不是 returning 两个单独的对象(类似于 ,但更封装):

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