如何给Python函数一个函数作为尚未调用的参数?

时间:2019-06-21 14:48:05

标签: python python-3.x function

我想用另一个函数作为参数来调用一个函数,该函数尚未定义和可调用。有pythonic的方法如何做到这一点吗?

我知道您可以将一个函数作为另一个函数的参数,如以下答案所示:

Python function as a function argument?

但是对于某种尚未定义和可调用的函数,这是不可能的。

我最近写了很多重复的代码,我很确定必须有更多的Python方式来做到这一点。

重复代码:

import pymysql

def database_connection():
    return pymysql.connect(db="MyDatabase", user='root', host="127.0.0.1", password="SecretPassword")

def mysql_request_true(sql_text):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = True
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()


def mysql_request_database_id(sql_text):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = cursor.lastrowid
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()


def mysql_request_fetchone(sql_text):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = cursor.fetchone()
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()


def mysql_request_fetchall(sql_text):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = cursor.fetchall()
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()

我想要达到的目标:

import pymysql

def database_connection():
    return pymysql.connect(db="MyDatabase", user='root', host="127.0.0.1", password="SecretPassword")

def mysql_request(sql_text, cmd):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = cmd
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()

def mysql_request_true(sql_text):
    return mysql_request(sql_text, True)

def mysql_request_database_id(sql_text):
    return mysql_request(sql_text, cmd=cursor.lastrowid)

def mysql_request_fetchone(sql_text):
    return mysql_request(sql_text, cmd=cursor.fetchone())

def mysql_request_fetchall(sql_text):
    return mysql_request(sql_text, cmd=cursor.fetchall())

上面的代码示例不起作用,因为当我将其作为参数时,尚未定义光标。

有人知道该怎么做吗?非常感谢您的回答。

3 个答案:

答案 0 :(得分:2)

因此,我认为您可能遇到的问题是每个功能都需要一个游标,但不想每次都重复创建游标的调用。解决此问题的一种方法是提供光标的包装函数:

from functools import wraps


def with_cursor(func):
    @wraps(func)
    def decorator_function(self, *args, **kwargs):
        cursor = connection.cursor()
        context = func(self, cursor, *args, **kwargs)
        cursor.close()
        return context

    return decorator_function

通过这种方式,每个函数都将游标作为第一个参数,但是可以确保它可用。

答案 1 :(得分:1)

您可以使用简单的lambda来推迟解析函数的名称:

def my_func(param, cmd=lambda: this_is_not_yet_defined_fn):
    print(cmd()(param))

this_is_not_yet_defined_fn = sum

my_func([1, 2])

打印:

3

答案 2 :(得分:1)

我认为您可以使用lambda获得所需的行为。只需将提取cursor所需功能的函数作为参数传递给您mysql_request函数,如下所示:

def mysql_request(sql_text, cmd):
    connection = database_connection()
    try:
        with connection.cursor() as cursor:
            cursor.execute(sql_text)
            result = cmd(cursor) # Call cmd which extracts the desired information
        connection.commit()
        return result
    except ConnectionError:
        return False
    finally:
        connection.close()

然后,您可以将cmd参数作为lambda函数传递:

def mysql_request_true(sql_text):
    return mysql_request(sql_text, lambda cursor:True)

def mysql_request_database_id(sql_text):
    return mysql_request(sql_text, lambda cursor:cursor.lastrowid)

def mysql_request_fetchone(sql_text):
    return mysql_request(sql_text, lambda cursor:cursor.fetchone())

def mysql_request_fetchall(sql_text):
    return mysql_request(sql_text, lambda cursor:cursor.fetchall())