views:

114

answers:

5

Hi guys,

Assume you have a programme with multiple functions defined. Each function is called in a separate for loop. Is it possible to specify which function should be called via the command line?

Example:

python prog.py -x <<<filname>>>

Where -x tells python to go to a particular for loop and then execute the function called in that for loop?

Thanks, Seafoid.

+4  A: 

the python idiom for the main entry point:

if __name__ == '__main__':
    main()

replace main() by whatever function should go first ... (more on if name ...: http://effbot.org/pyfaq/tutor-what-is-if-name-main-for.htm)

if you want to specify the function to run via command line argument, just check these arguments, either manually or via some helpers, e.g. http://docs.python.org/library/optparse.html, then branch of to the desired function.

If you don't want stuff like this:

if options.function_to_call == 'mydesiredfunction':
    mydesiredfunction()

you can take advantage of getattr.

And finally, another 'generic' approach using globals (exception handling excluded):

$ cat 1933407.py

#!/usr/bin/env python
# coding: utf-8

import sys

def first():
    print '1 of 9'

def second():
    print '2 of 9'

def seventh():
    print '7 of 9'

if __name__ == '__main__':
    globals()[sys.argv[1]]()

Meanwhile at the command line ...

$ python 1933407.py second
2 of 9
The MYYN
Won't this allow me to run `sys.exit` and the likes?
abyx
@abyx: `sys.exit` and the likes are easily avoidable by using prefix: `getattr(__import__(__name__), 'f_'+sys.argv[1], 'print_help')()`
J.F. Sebastian
A: 

Yes, the built in functions 'exec()' and 'eval()' are your friends. Just add '()' to the name of the function. However, you should wonder whether this is the best solution for the actual problem. The fact that it is technically possible does not mean it is also the best solution. Using 'exec()' and 'eval()' is generally considered 'to be avoided'.

Confusion
Minor note: exec is a statement, not a function: http://docs.python.org/reference/simple_stmts.html#exec
Peter Hansen
+3  A: 

You want the sys module.

For example:

import sys

#Functions
def a(filename): pass
def b(filename): pass
def c(filename): pass

#Function chooser
func_arg = {"-a": a, "-b": b, "-c": c}

#Do it
if __name__ == "__main__":
    func_arg[sys.argv[1]](sys.argv[2])

Which runs a(filename) if you run python file.py -a filename

me_and
+2  A: 

If you just want to use this to quickly test different functions during development and similar situations, you can use the -c command line parameter:

python -c 'import myfile; myfile.somefunc()'
sth
+1  A: 

A very simple way is the following:

import sys

x_is_set=False
for arg in sys.argv[1:]:
    if arg == '-x':   x_is_set=True

if x_is_set:
    print "-x is set"
Jabba