100% 工作 Python decorator DB Connector 在 VS Code 中显示错误

100% Working Python decorator DB Connector shows errors in VS Code

我创建了一个装饰器来处理这样的数据库连接:

def with_connection(f):
  def with_connection_(args, **kwargs):

    conn = mysql.connector.Connect("my redacted credentials")
    try:
        result = f(conn, args, **kwargs)
    except:
        conn.rollback()
        print("SQL failed")
        raise
    else:
        conn.commit()
    finally:
        conn.close()
    return result
return with_connection_

我这样称呼它:

@with_connection
def GetUsername(conn, args):
    Cursor = conn.cursor()
    query = "select user_name from users where user_id = %s"
    Cursor.execute(query, (args[0],))
    result = Cursor.fetchone()
    return result

user_name = DBQueries.GetUsername(user_id)

这段代码工作得很好。

然而,在 VS Code 中,我收到以下错误报告,我觉得我应该明白为什么会这样:

"message": "No value for argument 'args' in function call",

我有点明白了,因为 GetUsername 有 2 个参数,conn 和 args,而我用一个参数调用它,所以它认为它缺少 args 参数。但它有效。

谁能帮我解释一下这是怎么回事?

你的 IDE 基本上是混淆的,因为 GetUsername 确实需要不同的参数。在某些 IDE 中,这个问题可以通过用 @functools.wraps(f) 包装内部函数来解决。 (https://docs.python.org/3/library/functools.html#functools.wraps)。这基本上适当地处理了包装函数的元信息,使其类似于原始函数的信息。

您可以采用的另一种方法(但我仍然建议对这种方法也使用 functools.wraps)是从 kwargs 中获取连接参数,如下所示:

def with_connection(f):
    def with_connection_(*args, **kwargs):
        conn = mysql.connector.Connect("my redacted credentials")
        try:
            result = f(*args, connection=conn, **kwargs)
        except:
            conn.rollback()
            print("SQL failed")
            raise
        else:
            conn.commit()
        finally:
            conn.close()
        return result
    return with_connection_

@with_connection
def GetUsername(*args, **kwargs):
    conn = kwargs.pop("connection")
    Cursor = conn.cursor()
    query = "select user_name from users where user_id = %s"
    Cursor.execute(query, (args[0],))
    result = Cursor.fetchone()
    return result

其实也没有必要做 args[0],你可以这样做:

@with_connection
def GetUsername(user_id, *args, **kwargs):
    conn = kwargs.pop("connection")
    Cursor = conn.cursor()
    query = "select user_name from users where user_id = %s"
    Cursor.execute(query, (user_id,))
    result = Cursor.fetchone()
    return result