One of the recurrent problems I used to have when writing argument parsers is that after refactoring code, I also had to change the argument parser options which generally led to inconsistency between the arguments of the function and some of the options of the argument parser. The following example can illustrate the problem:
def main(a,b): """ This function adds together two numbers a and b param a: first number param b: second number """ print(a+b) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("--a", type=int, required=True, help="first number") parser.add_argument("--b", type=int, required=True, help="second number") args = parser.parse_args() main(**vars(args))
This code is nothing but a simple function that prints a+b and the argument parser asks for a and b. The perhaps not so obvious part is the invocation of the function in which we have ** and vars
. vars
converts the named tuple args
to a dictionary of the form {“a":1, "b":2}
, and ** expands the dictionary to be used as arguments for the function. So if you have main(**{"a":1, "b":2})
it is equivalent to main(a=1, b=2)
.
Let’s refactor the function so that we change the name of the argument a to num.
Continue reading