Are there best practices or style guidelines for working with Python's argparse
module?
I work with argparse
on a regular basis, and it quickly takes up a respectable number of lines to handle all the configuration. For almost everything I find that sticking close to PEP 8 results in clean, readable code, but not here. The end result is always an ugly block of code that is painful to read.
Painful to read is not Pythonic:
So is there a PEP or some other resource that provides guidelines for how to better format this code?
A sample of the ugliness (mostly following PEP 8):
parser = argparse.ArgumentParser(description='A nontrivial modular command')
subparsers = parser.add_subparsers(help='sub-command help')
parser_load = subparsers.add_parser('load', help='Load something somewhere')
parser_load.add_argument('--config',
help='Path to configuration file for special settings')
parser_load.add_argument('--dir', default=os.getcwd(),
help='The directory to load')
parser_load.add_argument('book', help='The book to load into this big thing')
parser_load.add_argument('chapter', nargs='?', default='',
help='Optionally specify a chapter')
parser_load.add_argument('verse', nargs='*',
help='Optionally pick as many verses as you want to'
' load')
parser_load.set_defaults(command='load')
parser_write = subparsers.add_parser(
'write', help='Execute commands defined in a config file')
parser_write.add_argument('config', help='The path to the config file')
parser_write.set_defaults(command='write')
parser_save = subparsers.add_parser(
'save',
help='Save this big thing for use somewhere later')
parser_save.add_argument('-n', '--name', default=None,
help='The name of the component to save')
parser_save.add_argument('path', help="The way out of Plato's cave")
parser_save.set_defaults(command='save')
...
args = parser.parse_args()
As commented by TemporalWolf, I would use line breaks more consistently, and more of them. Even if the code now appears longer, I find it easier to read:
help
string) requiredAdditionally, by renaming parser_X
/parser_Y
→ X_parser
/Y_parser
you could make it easier to distinguish X
/Y
.
parser = argparse.ArgumentParser(
description='A nontrivial modular command'
)
subparsers = parser.add_subparsers(
help='sub-command help'
)
load_parser = subparsers.add_parser(
'load',
help='Load something somewhere'
)
load_parser.add_argument(
'--config',
help='Path to configuration file for special settings'
)
load_parser.add_argument(
'--dir',
default=os.getcwd(),
help='The directory to load'
)
load_parser.add_argument(
'book',
help='The book to load into this big thing'
)
load_parser.add_argument(
'chapter',
nargs='?',
default='',
help='Optionally specify a chapter'
)
load_parser.add_argument(
'verse',
nargs='*',
help='Optionally pick as many verses as you want to load'
)
load_parser.set_defaults(
command='load'
)
write_parser = subparsers.add_parser(
'write',
help='Execute commands defined in a config file'
)
write_parser.add_argument(
'config',
help='The path to the config file'
)
write_parser.set_defaults(
command='write'
)
save_parser = subparsers.add_parser(
'save',
help='Save this big thing for use somewhere later'
)
save_parser.add_argument(
'-n', '--name',
default=None,
help='The name of the component to save'
)
save_parser.add_argument(
'path',
help="The way out of Plato's cave"
)
save_parser.set_defaults(
command='save'
)
...
args = parser.parse_args()