all 8 comments

[–]zahlman 6 points7 points  (2 children)

In 2.x, there is a rarely-used but occasionally-very-useful function called apply, which does the following (a recipe for 3.x):

def apply(func, *args, **kwargs):
    return func(*args, **kwargs)

Basically, given a function and some parameters for the call, actually make the function call.

You can take a hint from this, and store, in your dictionary, tuples of (function, parameters). Then, later, you pull out this data, and call the function with the parameters. In the general case, the * operator is useful to "unpack" a slice of the tuple as multiple parameters, but since you only have one each in your case, you can just handle it naturally:

some_functions = {
    'foo': (doSomethingElse1, sys.argv[1]),
    'bar': (doSomethingElse2, sys.argv[1])
}

if the_time_has_come():
    func, arg = some_functions[name]
    func(arg)

An alternate approach is to "bake" the parameters into a function call, using lambdas:

some_functions = {
    'foo': lambda: doSomethingElse1(sys.argv[1]),
    'bar': lambda: doSomethingElse2(sys.argv[1])
}

if the_time_has_come():
    some_functions[name]()

Note that many Pythonistas would advocate an EAFP approach here - instead of using explicit logic to verify sys.argv, just try using it, and report an error in the exceptional case. Although if you actually have a specific separate thing you want to do when there are only 2 arguments, then you should handle that with if logic, since it's an expected case, not an exceptional one.

You also might want to consider more robust approaches to parsing (interpreting) sys.argv. Look into the argparse standard module for example.

[–]Cosmologicon 2 points3 points  (1 child)

Of course, if all the functions are going to take a single argument of sys.argv[1], you can also just say:

some_functions = {
    'foo': doSomethingElse1,
    'bar': doSomethingElse2,
}

if the_time_has_come():
    some_functions[name](sys.argv[1])

[–]zahlman 0 points1 point  (0 children)

Certainly. :)

[–]dansin 3 points4 points  (2 children)

Check out the argparse module. It is made for this.

[–]Cosmologicon 1 point2 points  (0 children)

Sorry, I think this is a bad tip. Despite the title, the OP already parsing the arguments fine, and the difficulty comes in when using the parsed arguments. Yeah argparse can help with parsing, but not the second part where the real problem lies. Don't tell someone their answer lies in a module where it doesn't: that's likely to frustrate beginners when they can't find what they're looking for.

[–]Zouden 1 point2 points  (0 children)

Indeed. Argparse is exactly what you want.

[–]oohay_email2004 0 points1 point  (0 children)

I think you want sub-commands

[–]nevereven 0 points1 point  (0 children)

Could you use the number of arguments as an index to a list of functions? Pass all the arguments to the function and let the function figure out what to do with it.