20

With the following code:

import argparse
parser = argparse.ArgumentParser(description="Prepare something code.")
parser.add_argument("-t","--tabular", help="print something in tabular way for EXCEL",
                      action="store_true")
parser.add_argument("-v","--verbose", action="store_true")
args = parser.parse_args()
if args.tabular:
    print "Tabular print"
elif args.verbose:
    print "VERBOSE"

It's only when I execute it the following way, that it prints usage:

$ python mycode.py -h
usage: mycode.py [-h] [-t] [-v]

Prepare something code.

optional arguments:
  -h, --help     show this help message and exit
  -t, --tabular  print something in tabular way for EXCEL
  -v, --verbose

What I want to do is to simply run the code: $ my code.py without any -h option whatsoever to print the usage. How can I do that?

Brunisboy
  • 123
  • 1
  • 19
neversaint
  • 60,904
  • 137
  • 310
  • 477
  • 1
    If you expect exactly one of `-t` or `-v` to be used, you might consider having a single positional parameter with `choices=("tabular", "t", "verbose", "v")` instead. – chepner Mar 13 '14 at 03:52
  • 3
    That 2010 question only had 1 answer, and it isn't a particularly simple or obvious one. – hpaulj Mar 13 '14 at 04:03
  • @chepner: Can you give specific code. You're right I need exactly one of -t or -v to be used. – neversaint Mar 13 '14 at 04:19

3 Answers3

21

That 2010 question covers the same thing, but only has 1 answer. While that answer comes indirectly from the designer of argparse, it does not cover all possibilities.

Here's one which surprised me as to its simplicity:

import sys
parser = ...
if len(sys.argv)==1:
    parser.print_help()
    # parser.print_usage() # for just the usage line
    parser.exit()
args = parser.parse_args()

Yes you can check all the namespace args for default values, but that gets old if there are many arguments. But here I am just checking whether there are any argument strings. If none, then call the parser's own help function.

ipython does something like this to generate help. It checks sys.argv for some version of help, and produces its own help message(s), before even defining the parser.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • 1
    This is much simpler solution than the alternatives if you only have a bunch of optional arguments but the program needs at least one of those provided to do something meaningful. – timgeb Nov 20 '17 at 13:38
  • 3
    `len(sys.argv[1:])==0` is a long-winded way to write `len(sys.argv)==1`. – Kaz Oct 08 '19 at 20:28
3
import argparse
parser = argparse.ArgumentParser(description="Prepare something code.")
parser.add_argument("-t","--tabular", help="print something in tabular way for EXCEL",
                      action="store_true")
parser.add_argument("-v","--verbose", action="store_true")
args = parser.parse_args()
if args.tabular:
    print "Tabular print"
elif args.verbose:
    print "VERBOSE"
else:
    print parser.print_help()
hd1
  • 33,938
  • 5
  • 80
  • 91
1

If you need exactly one of "-t" or "-v" be used, they aren't really optional. I'd use a positional parameter instead:

import argparse
parser = argparse.ArgumentParser(description="Prepare something code.")
parser.add_argument("type", choices=("tabular", "verbose", "t", "v"))
args = parser.parse_args()
if args.type in ("tabular", "t"):
    print "Tabular print"
else:  # Must be "verbose" or "v"
    print "VERBOSE"

Then your program would be called using one of the following:

$ my_code t
$ my_code tabular
$ my_code v
$ my_code verbose

No argument would produce

$ my_code
usage: my_code [-h] {tabular,verbose,t,v}
my_code: error: too few arguments
chepner
  • 497,756
  • 71
  • 530
  • 681