在Python中挂起函数调用以便稍后传递(函数范式)
我正在写一个Python命令行程序,这个程序有一些相互依赖的选项,我希望用户可以随意输入这些选项的顺序。
现在我使用getopts库来解析命令行选项,但这个库是按顺序解析的。我想了一个办法,使用布尔标志来推迟处理某些命令行参数,直到处理它们依赖的那个参数。不过,我有个想法,使用一个优先队列来存储函数调用,这样在所有命令行选项解析完后再执行。
我知道Python可以把函数存储在变量名下,但这样似乎会立即调用这个函数。
举个例子:
help = obj.PrintHelp()
heapq.heappush(commandQ, (0, help))
这段代码会立即打印帮助信息。我该怎么做才能让我的代码在给PrintHelp一个名字时,不立即调用它呢?
编辑:哦,我刚意识到我把东西放进了一个叫help的队列,这是我的错误。
谢谢你提醒我去掉PrintHelp后面的()。
如果我现在想调用一个需要除了self以外更多参数的函数呢?
myFun = obj.parseFile(path)
heapq.heappush(commandQ, (1, myFun))
我是不是只需要把元组做大一点,传入命令行参数就行了?
3 个回答
如果你想在Python中保存一个完整的函数调用,有两种方法可以做到:
# option 1: hold the parameters separately
# I've also skipped saving the function in a 'help' variable'
heapq.heappush(commandQ, (0, obj.PrintHelp, param1, param2))
# later:
command = commandQ[0]
heapq.heappop(commandQ)
command[1](*command[2:]) # call the function (second item) with args (remainder of items)
另外,你也可以用一个助手来通过lambda
把参数打包起来:
# option 2: build a no-argument anonymous function that knows what arguments
# to give the real one
# module scope
def makeCall(func, *args):
return lambda: func(*args)
# now you can:
help = makeCall(obj.PrintHelp, param1, param2)
heapq.heappush(commandQ, (0, help))
如果你需要关键字参数,告诉我,我会帮你处理这些。
如果你这样使用 heappush
:
myFun = obj.parseFile
heapq.heappush(commandQ, (1, myFun, path))
那么之后要调用这个函数,你可以这样做:
while commandQ:
x=heapq.heappop(commandQ)
func=x[1]
args=x[2:]
func(*args)
使用
help = obj.PrintHelp
时不要加括号。这样做是为了让 help
指向这个函数。之后,你可以用 help()
来调用这个函数。
另外,如果我理解你的情况没错,你其实可以直接使用标准库里的 optparse 模块,或者如果你用的是 Python2.7 或更高版本,可以用 argparse 模块,这样可以处理命令行选项,无论顺序如何。
顺便说一下,help
是 Python 内置的一个函数。如果你把一个变量命名为 help
,就会覆盖掉这个内置函数,这样访问内置函数会变得困难(虽然不是不可能)。一般来说,最好不要覆盖内置函数的名字。