9

So I'm stuck on a project I'm working on that involves the command line in python.

So basically, here's what I'm trying to accomplish:

I have a set of functions in a class, say,

def do_option1(self, param1, param2) :
    #some python code here

def do_option2(self, param1): 
    #some python code here

def do_option3(self, param1, param2, param3):
    #some python code here

And so basically, when a user puts filename.py option2 param1 into the command line, I want it to call the function do_option2 and pass the parameter, param1, to it.

Similarly, when a user puts filename.py option3 param1 param2 param3, I want it to execute the do_option3 function with the given parameters.

I know there are 2 modules in python called argparse and optparse, but I've had difficulty understanding the two and i'm not sure if either of the two alone will accomplish what I need done.

kylieCatt
  • 10,672
  • 5
  • 43
  • 51
lesley2958
  • 2,538
  • 4
  • 15
  • 15
  • From a learning perspective, I'd suggest first getting your information directly from `sys.argv`. You can use a sequence of `if` statements, or the dictionary dispatching. If you need to add more options, then take the time to learn `argparse`. Your problem fits the `subparsers` model nicely. – hpaulj Jun 05 '15 at 15:20

5 Answers5

11

Using argparse subcommand parsers

p = argparse.ArgumentParser()
subparsers = p.add_subparsers()

option1_parser = subparsers.add_parser('option1')
# Add specific options for option1 here, but here's
# an example
option1_parser.add_argument('param1')
option1_parser.set_defaults(func=do_option1)

option2_parser = subparsers.add_parser('option2')
# Add specific options for option1 here
option2_parser.set_defaults(func=do_option2)

option3_parser = subparsers.add_parser('option3')
# Add specific options for option3 here
option3_parser.set_defaults(func=do_option3)

args = p.parse_args()
args.func(args)

Then each of your do_option functions would need to be rewritten slightly to take a single argument from which it can extract the values it needs. For example:

def do_option1(args):
    param1 = args.param1
    # And continue
chepner
  • 497,756
  • 71
  • 530
  • 681
6

I use this template that may help you out.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--option1', help='description for option1')
parser.add_argument('--option2', help='description for option2')
parser.add_argument('--option3', help='description for option3')

args = parser.parse_args()

if args.option1:
    ...do something

if args.option2:
    ...do something

if args.option3:
    ...do something

You can then run your script passing the arguments like this:

python script.py --option1 my-option1 --option3 my-option3 --option2 my-option2

Note that the position of the arguments is not important since you specify the name of the argument before its value.

alec_djinn
  • 10,104
  • 8
  • 46
  • 71
4
options = {
    'option_1': my_class.option_1,
    'option_2': my_class.option_2,
    'option_3': my_class.option_3,
}

option, params = sys.argv[0], sys.argv[1:]
options[option](*params)

Should do the trick. You'll probably want to add some checking to make sure that the user is passing at least some arguments to your script.

kylieCatt
  • 10,672
  • 5
  • 43
  • 51
  • I don't follow how this works (probably my own shortcoming) ... doesn't `sys.argv[0]` return the name of the script that was run, rather than a function? – James Jan 03 '23 at 20:54
2

Execute function via arg

As stated in the accepted answer, you can (ab?)use the type parameter of add_argument to execute a function.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('option2', type=interface.do_option2)

args = parser.parse_args()
Community
  • 1
  • 1
Joonazan
  • 1,408
  • 10
  • 18
  • 1
    Good starting point but it would be preferable, I think, to go with [sub commands](https://docs.python.org/2.7/library/argparse.html?highlight=argparse#sub-commands) (as in the second last example). – Gall Jun 05 '15 at 14:23
1

If you want to directly pass in the parameters without using tags, you can just use the sys module: sys.argv will give you ['filename.py', 'option3', 'param1', 'param2', 'param3'] for the command line of filename.py option3 param1 param2 param3

http://www.tutorialspoint.com/python/python_command_line_arguments.htm

kponz
  • 508
  • 3
  • 7
  • Hi! Thanks for the response. So in my main function, I have, interface = Interface() interface.prompt(">") interface.cmdloop("Starting prompt...") Interface is the class with the functions. So with sys.argv I can call a certain function and pass those arguments along with it, at the same time? – lesley2958 Jun 05 '15 at 14:12
  • Just use an if statement to decide which function to call: `if sys.argv[1]=='option3':` , etc. – kponz Jun 05 '15 at 14:25
  • `sys.argv` has all of the command line elements in it, so you can parse from it anything that is added as arguments to the command line – kponz Jun 05 '15 at 14:28