There are several third-party libraries for command-line argument parsing, but the standard library module argparse is no slouch either.
Without adding any more dependencies, you can write a nifty command-line tool with useful argument parsing.
Argument parsing in Python
When parsing command-line arguments with argparse, the first step is to configure an ArgumentParser object. This is often done at the global module scope since merely configuring the parser has no side effects.
import argparse
PARSER = argparse.ArgumentParser()The most important method on ArgumentParser is .add_argument(). It has a few variants. By default, it adds an argument that expects a value.
PARSER.add_argument("--value")To see it in action, call the method .parse_args():
PARSER.parse_args(["--value", "some-value"])Namespace(value='some-value')It's also possible to use the syntax with =:
PARSER.parse_args(["--value=some-value"])Namespace(value='some-value')You can also specify a short "alias" for a shorter command line when typed into the prompt:
PARSER.add_argument("--thing", "-t")It's possible to pass either the short option:
PARSER.parse_args("-t some-thing".split())Namespace(value=None, thing='some-thing')or the long one:
PARSER.parse_args("--thing some-thing".split())Namespace(value=None, thing='some-thing')Types
There are more types of arguments available. The two most popular ones, after the default, are boolean and counting. The booleans come with a variant that defaults to true, and one that defaults to false.
PARSER.add_argument("--active", action="https://opensource.com/store_true")
PARSER.add_argument("--no-dry-run", action="https://opensource.com/store_false", dest="dry_run")
PARSER.add_argument("--verbose", "-v", action="https://opensource.com/count")This means that active is False unless --active is passed, and dry_run is True unless --no-dry-run is passed. Short options without value can be juxtaposed.
Passing all the arguments results in a non-default state:
PARSER.parse_args("--active --no-dry-run -vvvv".split())Namespace(value=None, thing=None, active=True, dry_run=False, verbose=4)The default is somewhat less exciting:
PARSER.parse_args("".split())Namespace(value=None, thing=None, active=False, dry_run=True, verbose=None)Subcommands
Though classic Unix commands "did one thing, and did it well," the modern tendency is to do "several closely related actions."
The examples of git, podman, and kubectl can show how popular the paradigm is. The argparse library supports that too:
MULTI_PARSER = argparse.ArgumentParser()
subparsers = MULTI_PARSER.add_subparsers()
get = subparsers.add_parser("get")
get.add_argument("--name")
get.set_defaults(command="get")
search = subparsers.add_parser("search")
search.add_argument("--query")
search.set_defaults(command="search")MULTI_PARSER.parse_args("get --name awesome-name".split())Namespace(name='awesome-name', command='get')MULTI_PARSER.parse_args("search --query name~awesome".split())Namespace(query='name~awesome', command='search')Anatomy of a program
One way to use argparse is to structure the program as follows:
## my_package/__main__.py
import argparse
import sys
from my_package import toplevel
parsed_arguments = toplevel.PARSER.parse_args(sys.argv[1:])
toplevel.main(parsed_arguments)## my_package/toplevel.py
PARSER = argparse.ArgumentParser()
## .add_argument, etc.
def main(parsed_args):
...
# do stuff with parsed_args
In this case, running the command is done with python -m my_package. Alternatively, you can use the console_scripts entry points in the package's setup.
Summary
The argparse module is a powerful command-line argument parser. There are many more features that have not been covered here. The limit is your imagination.

1 Comment