[英]How to give a Python function a function as an argument which is not yet callable?
I would like to call a function with another function as argument, which is not yet defined and callable.我想用另一个函数作为参数调用一个函数,该函数尚未定义和可调用。 Is there a pythonic way how to do this?
有没有一种pythonic的方法来做到这一点?
I know that you can give a function as an argument for another function, like this answer suggests:我知道您可以将一个函数作为另一个函数的参数,就像这个答案所暗示的那样:
Python function as a function argument? Python函数作为函数参数?
But this somehow is not possible for functions which are not yet defined and callable.但是对于尚未定义和可调用的函数,这在某种程度上是不可能的。
I wrote a lot of those repetitive code recently and I'm pretty sure there must be a more pythonic way to do this.我最近写了很多重复的代码,我很确定一定有一种更 Pythonic 的方法来做到这一点。
Repetitive code:重复代码:
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()
What I try to achieve:我试图实现的目标:
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())
The code sample above does not work, because cursor is not yet defined when I give it as an argument.上面的代码示例不起作用,因为当我将它作为参数提供时,游标尚未定义。
Does anybody know how to do this?有人知道怎么做这个吗? Thank you very much for your answers.
非常感谢您的回答。
So I think the issue you might have is that you need a cursor for each function, but do not want to repeat the call to create a cursor each time.所以我认为您可能遇到的问题是每个函数都需要一个游标,但不想每次都重复调用以创建游标。 One way to counteract this would be a wrapper function which provided a cursor:
抵消这种情况的一种方法是提供一个游标的包装函数:
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
In this way, each function takes cursor as the first argument, but can then be sure it is available.这样,每个函数都将光标作为第一个参数,但可以确保它可用。
You can defer resolving the function's name with simple lambda
:您可以使用简单的
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])
Prints:印刷:
3
I think you can get the desired behavior using lambda
.我认为您可以使用
lambda
获得所需的行为。 Just pass a function extracting the desired feature of cursor
as an argument to you mysql_request
function as such:只需将提取所需
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()
Then you can pass the cmd
argument as a lambda function:然后您可以将
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())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.