Python动态函数生成
我正在使用PyQt,想根据一个字符串列表来创建一个菜单。
问题是,当我想调用'addAction'时,它需要一个回调函数(针对每个字符串),而这个函数不能接受任何参数。
对于简单的菜单来说,这样是没问题的,比如:
menu.addAction("Open", self.open)
menu.addAction("Exit", self.quit)
但是,我想只用一个函数,并把'动作字符串'作为参数传进去。
我在想Python能不能做到这一点:
def f(x, y):
print x + 2*y
# These 2 variables are of type: <type 'function'>
callback1 = f
callback2 = f(x=7, *)
# NB: the line above is not valid python code.
# I'm just illustrating my desired functionality
print callback1(2,5) # prints 12
print callback2(5) # prints 17
这是我的代码片段:
def printParam(parameter):
print "You selected %s" % parameter
# parameters = list of strings
menu_bar = QMenuBar()
menu = menu_bar.addMenu('Select Parameter')
for parameter in parameters:
# This line will not work because the action does not pass in
# any arguments to the function
menu.addAction(parameter, printParam)
非常感谢任何建议
5 个回答
2
是的,这个叫做部分应用。标准库里有一个类可以用来部分应用一个函数,叫做 functools.partial
。在你的例子中,你可以写 partial(f, x=7)
或者 partial(f, 7)
(因为这是一个位置参数,你不需要跳过任何位置参数)。
6
functools.partial() 这个功能可以让你提前提供一些参数。这样一来,你就可以根据自己的需要创建自定义的回调函数。
>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
4
你可以使用一个闭包,像这样:
def printParam(parameter):
def callback():
print "You selected %s" % parameter
return callback
for parameter in parameters:
menu.addAction(parameter, printParam(parameter))