Python Argparse
The argparse
module makes it easy to write user-friendly
command-line interfaces. It parses the defined arguments from the
sys.argv
.
The argparse
module also automatically generates help and usage
messages, and issues errors when users give the program invalid arguments.
The argparse
is a standard module; we do not need to install it.
A parser is created with ArgumentParser
and a new parameter is
added with add_argument
. Arguments can be optional, required, or
positional.
Python Argparse Optional Argument
The following example creates a simple argument parser.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('-o', '--output', action='store_true', help="shows output") args = parser.parse_args() if args.output: print("This is some output")
The example adds one argument having two options: a short -o
and
a long --ouput
. These are optional arguments.
import argparse
The module is imported.
parser.add_argument('-o', '--output', action='store_true', help="shows output")
An argument is added with add_argument
. The action
set to store_true
will store the argument as True
, if present.
The help option gives argument help.
args = parser.parse_args()
The arguments are parsed with parse_args
. The parsed arguments are
present as object attributes. In our case, there will be
args.output
attribute.
if args.output: print("This is some output")
If the argument is present, we show some output.
$ optional_arg.py -o This is some output $ optional_arg.py --output This is some output
We run the program with the -o
and --output
.
We can show the program help.
Python Argparse Required Argument
An argument is made required with the required
option.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('--name', required=True) args = parser.parse_args() print(f'Hello {args.name}')
The example must have the name
option specified; otherwise
it fails.
$ required_arg.py --name Peter Hello Peter $ required_arg.py usage: required_arg.py [-h] --name NAME required_arg.py: error: the following arguments are required: --name
Python argparse positional arguments
The following example works with positional arguments. They
are created with add_argument
.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('name') parser.add_argument('age') args = parser.parse_args() print(f'{args.name} is {args.age} years old')
The example expects two positional arguments: name and age.
parser.add_argument('name') parser.add_argument('age')
Positional arguments are created without the dash prefix characters.
$ positional_arg.py Peter 23 Peter is 23 years old
This is sample output.
Python argparse dest
The dest
option of the add_argument
gives
a name to the argument. If not given, it is inferred from the option.
#!/usr/bin/env python import argparse import datetime parser = argparse.ArgumentParser() parser.add_argument('-n', dest='now', action='store_true', help="shows now") args = parser.parse_args() if args.now: now = datetime.datetime.now() print(f"Now: {now}")
The program gives the now
name to the -n
argument.
$ dest.py -n Now: 2019-03-22 17:37:40.406571
Python argparse type
The type
argument determines the argument type.
#!/usr/bin/env python import argparse import random parser = argparse.ArgumentParser() parser.add_argument('-n', type=int, required=True, help="define the number of random integers") args = parser.parse_args() n = args.n for i in range(n): print(random.randint(-100, 100))
The program shows n random integers from -100 to 100.
parser.add_argument('-n', type=int, required=True, help="define the number of random integers")
The -n
option expects integer value and it is
required.
$ rand_int.py -n 3 92 -61 -61
This is a sample output.
Python argparse default
The default
option specifies the default value,
if the value is not given.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('-b', type=int, required=True, help="defines the base value") parser.add_argument('-e', type=int, default=2, help="defines the exponent value") args = parser.parse_args() val = 1 base = args.b exp = args.e for i in range(exp): val *= base print(val)
The example computes exponentiation. The exponent value is not required; if not given, the default will be 2.
$ power.py -b 3 9 $ power.py -b 3 -e 3 27
Python argparse metavar
The metavar
option gives a name to the
expected value in error and help outputs.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('-v', type=int, required=True, metavar='value', help="computes cube for the given value") args = parser.parse_args() print(args) val = args.v print(val * val * val)
The example names the expected value value
. The default
name is V
.
$ metavar.py -h usage: metavar.py [-h] -v value optional arguments: -h, --help show this help message and exit -v value computes cube for the given value
The given name is shown in the help output.
Python argparse append action
The append
action allows to group repeating
options.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('-n', '--name', dest='names', action='append', help="provides names to greet") args = parser.parse_args() names = args.names for name in names: print(f'Hello {name}!')
The example produces greeting messages to all names specified with the
n
or name
options; they can be repeated
multipile times.
$ appending.py -n Peter -n Lucy --name Jane Hello Peter! Hello Lucy! Hello Jane!
Python argparse nargs
The nargs
specifies the number of command-line arguments
that should be consumed.
#!/usr/bin/env python import argparse import sys parser = argparse.ArgumentParser() parser.add_argument('chars', type=str, nargs=2, metavar='c', help='starting and ending character') args = parser.parse_args() try: v1 = ord(args.chars[0]) v2 = ord(args.chars[1]) except TypeError as e: print('Error: arguments must be characters') parser.print_help() sys.exit(1) if v1 > v2: print('first letter must precede the second in alphabet') parser.print_help() sys.exit(1)
The example shows a sequence of characters from character one to character two. It expects two arguments.
parser.add_argument('chars', type=str, nargs=2, metavar='c', help='starting and ending character')
With nargs=2
we specify that we expect two arguments.
$ charseq.py e k e f g h i j k
The program shows a sequence of characters from e to k.
Variable number of arguments can be set with the *
character.
#!/usr/bin/env python import argparse parser = argparse.ArgumentParser() parser.add_argument('num', type=int, nargs='*') args = parser.parse_args() print(f"The sum of values is {sum(args.num)}")
The example computes the sum of values; we can specify variable number of arguments to the program.
$ var_args.py 1 2 3 4 5 The sum of values is 15
Python argparse choices
The choices
option limits arguments
to the given list.
#!/usr/bin/env python import argparse import datetime import time parser = argparse.ArgumentParser() parser.add_argument('--now', dest='format', choices=['std', 'iso', 'unix', 'tz'], help="shows datetime in given format") args = parser.parse_args() fmt = args.format if fmt == 'std': print(datetime.date.today()) elif fmt == 'iso': print(datetime.datetime.now().isoformat()) elif fmt == 'unix': print(time.time()) elif fmt == 'tz': print(datetime.datetime.now(datetime.timezone.utc))
In the example, the now
option can accept the following
values: std
, iso
, unix
, or tz
.
$ mytime.py --now iso 2019-03-27T11:34:54.106643 $ mytime.py --now unix 1553682898.422863
This is a sample output.
Head example
The following example mimics the Linux head command. It shows the n lines of a text from the beginning of the file.
sky top forest wood lake wood
For the example, we have this small test file.
#!/usr/bin/env python import argparse from pathlib import Path parser = argparse.ArgumentParser() parser.add_argument('f', type=str, help='file name') parser.add_argument('n', type=int, help='show n lines from the top') args = parser.parse_args() filename = args.f lines = Path(filename).read_text().splitlines() for line in lines[:args.n]: print(line)
The example has two options: f
for a file name and
-n
for the number of lines to show.
$ head.py words.txt 3 sky top forest