Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use argparse arguments as function names

I want to implement the example from the Argparse intro:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                   const=sum, default=max,
                   help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

But in my case, I'd like to have a wider range of possible function names to choose from.

def a(): ...
def b(): ...
def c(): ...

parser.add_argument('-f', '--func', 
                     choices=[a, b, c], 
                     required=True,
                     help="""Choose one of the specified function to be run.""")
parser.func()

Using it like that doesn't work as intended, I get

$ python program.py -f=a
program.py: error: argument -f/--func: invalid choice: 'a' (choose from 
<function a at 0x7fa15f32f5f0>, 
<function b at 0x7fa15f32faa0>, 
<function c at 0x7ff1967099b0>)

I know I could solve it with basic string arguments and flow control, but it would be a lot less cluttered and easier to maintain if I could use parser arguments directly as function names.

like image 619
Arne Avatar asked Apr 15 '15 14:04

Arne


People also ask

How do you add arguments in Argparse?

After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments. To add your arguments, use parser. add_argument() .


1 Answers

You can use basic string arguments and minimize the clutter by using a dict to get the actual function from its name.

I'm on Python 2.6.6, so I can't use argparse, but this code should give you the general idea:

#!/usr/bin/env python

def a(): return 'function a'
def b(): return 'function b'
def c(): return 'function c'

func_list = [a, b, c]
func_names = [f.func_name for f in func_list]
funcs_dict = dict(zip(func_names, func_list))

f = funcs_dict['b']
print f()

output

function b

So you can pass func_names to argparse and compactly retrieve the desired function using funcs_dict.


In more recent Python versions, you should use f.__name__ instead of f.func_name. (That will also work in Python 2.6, but I was unfamiliar with the newer syntax when I wrote this answer).

like image 119
PM 2Ring Avatar answered Oct 22 '22 08:10

PM 2Ring