Getting started¶
Motivation¶
Suppose we want a simple script that adds or multiplies two numbers. This code should then be
callable inside python (i.e. we create a function)
executable from the command line
So let’s setup the function in a file called 'add_or_multiply.py'
like this
In [1]: def do_something(a, b, multiply=False):
...: """
...: Multiply or add one number to the others
...:
...: Parameters
...: ----------
...: a: int
...: Number 1
...: b: list of int
...: A list of numbers to add `a` to
...: multiply: bool
...: If True, the numbers are multiplied, not added
...: """
...: if multiply:
...: result = [n * a for n in b]
...: else:
...: result = [n + a for n in b]
...: print(result)
...:
Now, if you want to make a command line script out of it, the usual methodology
is to create an argparse.ArgumentParser
instance and parse the
arguments like this
In [2]: if __name__ == '__main__':
...: from argparse import ArgumentParser
...: parser = ArgumentParser(
...: description='Multiply or add two numbers')
...: parser.add_argument('a', type=int, help='Number 1')
...: parser.add_argument('b', type=int, nargs='+',
...: help='A list of numbers to add `a` to')
...: parser.add_argument('-m', '--multiply', action='store_true',
...: help='Multiply the numbers instead of adding them')
...: args = parser.parse_args('3 2 -m'.split())
...: do_something(**vars(args))
...:
Now, if you parse the arguments, you get
In [3]: parser.print_help()
usage: sphinx-build [-h] [-m] a b [b ...]
Multiply or add two numbers
positional arguments:
a Number 1
b A list of numbers to add `a` to
optional arguments:
-h, --help show this help message and exit
-m, --multiply Multiply the numbers instead of adding them
However, you could skip the entire lines above, if you just use the
funcargparse.FuncArgParser
In [4]: from funcargparse import FuncArgParser
In [5]: parser = FuncArgParser()
In [6]: parser.setup_args(do_something)
Out[6]: <function __main__.do_something(a, b, multiply=False)>
In [7]: parser.update_short(multiply='m')
In [8]: actions = parser.create_arguments()
In [9]: parser.print_help()
usage: sphinx-build [-h] [-m] int int [int ...]
Multiply or add one number to the others
positional arguments:
int Number 1
int A list of numbers to add `a` to
optional arguments:
-h, --help show this help message and exit
-m, --multiply If True, the numbers are multiplied, not added
or you use the parser right in the beginning as a decorator
In [10]: @parser.update_shortf(multiply='m')
....: @parser.setup_args
....: def do_something(a, b, multiply=False):
....: """
....: Multiply or add one number to the others
....:
....: Parameters
....: ----------
....: a: int
....: Number 1
....: b: list of int
....: A list of numbers to add `a` to
....: multiply: bool
....: If True, the numbers are multiplied, not added
....: """
....: if multiply:
....: result = [n * a for n in b]
....: else:
....: result = [n + a for n in b]
....: print(result)
....:
In [11]: actions = parser.create_arguments()
In [12]: parser.print_help()
usage: sphinx-build [-h] [-m] int int [int ...]
Multiply or add one number to the others
positional arguments:
int Number 1
int A list of numbers to add `a` to
optional arguments:
-h, --help show this help message and exit
-m, --multiply If True, the numbers are multiplied, not added
The FuncArgParser
interpretes the docstring
(see Interpretation guidelines for docstrings) and sets up the arguments.
Your '__main__'
part could then simply look like
In [13]: if __name__ == '__main__':
....: parser.parse_to_func()
....:
Usage¶
Generally the usage is
create an instance of the
FuncArgParser
classsetup the arguments using the
setup_args()
functionmodify the arguments (optional) either
in the
FuncArgParser.unfinished_arguments
dictionaryusing the
update_arg()
,update_short()
,update_long()
orappend2help()
methodsusing the equivalent decorator methods
update_argf()
,update_shortf()
,update_longf()
orappend2helpf()
create the arguments using the
create_arguments()
method
Subparsers¶
You can also use subparsers for controlling you program (see the
argparse.ArgumentParser.add_subparsers()
method). They can either be
implemented the classical way via
In [14]: subparsers = parser.add_subparsers()
In [15]: subparser = subparsers.add_parser('test')
And then as with the parent parser you can use function docstrings.
In [16]: @subparser.setup_args
....: def my_other_func(b=1):
....: """
....: Subparser summary
....:
....: Parameters
....: ----------
....: b: int
....: Anything"""
....: print(b * 500)
....:
In [17]: subparser.create_arguments()
Out[17]: [_StoreAction(option_strings=['-b'], dest='b', nargs=None, const=None, default=1, type=<class 'int'>, choices=None, help='Anything', metavar='int')]
In [18]: parser.print_help()