9

I write my scripts in python and run them with cmd by typing in:

C:\> python script.py

Some of my scripts contain separate algorithms and methods which are called based on a flag. Now I would like to pass the flag through cmd directly rather than having to go into the script and change the flag prior to run, I want something similar to:

C:\> python script.py -algorithm=2

I have read that people use sys.argv for almost similar purposes however reading the manuals and forums I couldn't understand how it works.

Kevin Bell
  • 277
  • 1
  • 5
  • 14
  • 1
    Have you checked the [argparse](http://docs.python.org/2.7/library/argparse.html) module ? Its documentation is quite clear and should get you started. – Pierre GM May 23 '13 at 11:33
  • @PierreGM I hadn't seen this before, does it mean that I can add `parser = argparse.ArgumentParser()` and `parser.add_argument(('--Algorithm")` and `args = parser.parse_args()` in my script and then in cmd type in `C:\> python script.py --Algorithm=2` so that Algorithm is set to 2 and the python script will run tasks associated with algoritm 2? – Kevin Bell May 23 '13 at 11:54

3 Answers3

17

There are a few modules specialized in parsing command line arguments: getopt, optparse and argparse. optparse is deprecated, and getopt is less powerful than argparse, so I advise you to use the latter, it'll be more helpful in the long run.

Here's a short example:

import argparse

# Define the parser
parser = argparse.ArgumentParser(description='Short sample app')

# Declare an argument (`--algo`), saying that the 
# corresponding value should be stored in the `algo` 
# field, and using a default value if the argument 
# isn't given
parser.add_argument('--algo', action="store", dest='algo', default=0)

# Now, parse the command line arguments and store the 
# values in the `args` variable
args = parser.parse_args()

# Individual arguments can be accessed as attributes...
print args.algo

That should get you started. At worst, there's plenty of documentation available on line (say, this one for example)...

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Pierre GM
  • 19,809
  • 3
  • 56
  • 67
  • What if, say, I write a language interpreter, How would I be able to hande an input file path `lang file.lang` for example... – J-Cake Apr 19 '18 at 06:52
10

It might not answer your question, but some people might find it usefull (I was looking for this here):

How to send 2 args (arg1 + arg2) from cmd to python 3:

----- Send the args in test.cmd:

python "C:\Users\test.pyw" "arg1" "arg2"

----- Retrieve the args in test.py:

print ("This is the name of the script= ", sys.argv[0])
print("Number of arguments= ", len(sys.argv))
print("all args= ", str(sys.argv))
print("arg1= ", sys.argv[1])
print("arg2= ", sys.argv[2])
JinSnow
  • 1,553
  • 4
  • 27
  • 49
1

Try using the getopt module. It can handle both short and long command line options and is implemented in a similar way in other languages (C, shell scripting, etc):

import sys, getopt


def main(argv):

    # default algorithm:
    algorithm = 1

    # parse command line options:
    try:
       opts, args = getopt.getopt(argv,"a:",["algorithm="])
    except getopt.GetoptError:
       <print usage>
       sys.exit(2)

    for opt, arg in opts:
       if opt in ("-a", "--algorithm"):
          # use alternative algorithm:
          algorithm = arg

    print "Using algorithm: ", algorithm

    # Positional command line arguments (i.e. non optional ones) are
    # still available via 'args':
    print "Positional args: ", args

if __name__ == "__main__":
   main(sys.argv[1:])

You can then pass specify a different algorithm by using the -a or --algorithm= options:

python <scriptname> -a2               # use algorithm 2
python <scriptname> --algorithm=2    # ditto

See: getopt documentation

ccbunney
  • 2,282
  • 4
  • 26
  • 42
  • Thanks for the answer, just a few quick questions, 1. What is the resposibility of `if __name__ == "__main__":`? 2. this a definition so can I or should I probably save it in a separate python script and then call in my actual script by `from xxx import *` and then `if __name__ == "__main__": main(sys.argv[1:])`? – Kevin Bell May 23 '13 at 12:04
  • @Kevin Bell, the test for `__name__ == "__main__"` will return true if the script is run from the command line, rather than imported in the python interpreter, or another script. The design is up to you - if you program is self contained in that single script, then you can just add the `__name__ == "__main__"` test to allow it to be launched from the command line. Otherwise, if you import the script, you will have to pass in the argv parameters to the main() call. – ccbunney May 23 '13 at 12:09
  • I had issues with it, don't know why but Thanks anyways. I got what I wanted with Pierre GM suggested. All the best – Kevin Bell May 23 '13 at 12:58