首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何给Python函数一个函数作为参数,而这个参数还不能被调用?

如何给Python函数一个函数作为参数,而这个参数还不能被调用?
EN

Stack Overflow用户
提问于 2019-06-21 22:48:06
回答 3查看 96关注 0票数 0

我想使用另一个函数作为参数来调用一个函数,该函数尚未定义且可调用。有没有一种巨蟒式的方法来做到这一点?

我知道您可以将一个函数作为另一个函数的参数,就像下面的答案所建议的那样:

Python function as a function argument?

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

我最近写了很多这样的重复代码,我非常确定一定有更多的pythonic方式来做这件事。

重复性代码:

代码语言:javascript
复制
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()

我试图实现的目标是:

代码语言:javascript
复制
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())

上面的代码示例不起作用,因为当我将游标作为参数提供时,它还没有定义。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-08 20:33:21

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

代码语言:javascript
复制
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函数传递:

代码语言:javascript
复制
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())
票数 1
EN

Stack Overflow用户

发布于 2019-06-21 22:52:32

因此,我认为您可能会遇到的问题是,每个函数都需要一个游标,但又不希望每次都重复调用以创建游标。解决这个问题的一种方法是使用包装器函数,它提供了一个光标:

代码语言:javascript
复制
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

这样,每个函数都将游标作为第一个参数,但随后可以确保它是可用的。

票数 2
EN

Stack Overflow用户

发布于 2019-06-21 22:55:08

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

代码语言:javascript
复制
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])

打印:

代码语言:javascript
复制
3
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56705716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档