开发者

Suspending function calls in Python for passing later (functional paradigm)

开发者 https://www.devze.com 2023-01-15 18:37 出处:网络
I\'m writing a python command line program which has some interdependent options, I would like for the user to be able to enter the options in whichever order they please.

I'm writing a python command line program which has some interdependent options, I would like for the user to be able to enter the options in whichever order they please.

Currently I am using the getopts library to parse the command line options, unfortunately that parses them in-order. I've thrown together a system of boolean flags to leave the processing of certain command line arguments until the one they're dependent on is processed, however I had the idea of using a Priority Queue of function calls which would execute after all the command line options are parsed.

I know that Python can store functions under variable names, but that seems to call the function at the same time.

For example:

help = obj.PrintH开发者_如何学Goelp()
heapq.heappush(commandQ, (0, help))

Will print the help dialog immediately. How would I go about implementing my code such that it won't call PrintHelp() immediately upon assigning it a name.

EDIT: Oh i just realized I was pushing into a queue called help, that's my mistake.

Thanks for the tip on removing the () after PrintHelp.

What if I want to now call a function that requires more than the self argument?

myFun = obj.parseFile(path)
heapq.heappush(commandQ, (1, myFun))

Would I just make the tuple bigger and take the command line argument?


If you heappush like this:

myFun = obj.parseFile
heapq.heappush(commandQ, (1, myFun, path))

then to later call the function, you could do this:

while commandQ:
    x=heapq.heappop(commandQ)
    func=x[1]
    args=x[2:]
    func(*args)

Use

help = obj.PrintHelp

without the parentheses. This makes help reference the function. Later, you can call the function with help().

Note also (if I understand your situation correctly), you could just use the optparse or (if you have Python2.7 or better) argparse modules in the standard library to handle the command-line options in any order.

PS. help is a built-in function in Python. Naming a variable help overrides the built-in, making it difficult (though not impossible) to access the built-in. Generally, it's a good idea not to overwrite the names of built-ins.


Instead of using getopts, I would suggest using optparse (argparse, if you are using a newer python version): most probably, you will get everything you need, already implemented.

That said, in your example code, you are actually calling the function, while you should simply get its name:

help = obj.PrintHelp 
heapq.heappush(help, (0, help)) 


If you want to store a complete function call in Python, you can do it one of two ways:

# 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)

Alternatively, you can use a helper to package the arguments up via 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))

If you need keyword arguments, let me know and I'll edit to take care of those too.

0

精彩评论

暂无评论...
验证码 换一张
取 消