[Tutor] Argparse functions with N parameters

Peter Otten __peter__ at web.de
Tue May 7 18:10:49 CEST 2013


Danilo Chilene wrote:

> Hello,
> 
> I have the code below:
> 
> import argparse
> class Myclass(object):
> 
>     def foo(self):
>         print 'foo'
> 
>     def bar(self):
>         print 'bar'
> 
>     def test(self,name,place):
>         print name, place
> 
> class Main(Myclass):
>     def __init__(self):
>         foo_parser = argparse.ArgumentParser()
>         foo_parser.add_argument('method')
>         self.args = foo_parser.parse_args()
> 
>     def __call__(self, *args, **kws):
>         method = self.args.method
>         return getattr(self, method)(*args, **kws)
> 
> if __name__ == "__main__":
>     main = Main()
> 
>     main()
> 
> It's working for functions foo and bar:
> 
> 5: python arg.py foo
> foo
> 
> 5: python arg.py bar
> bar
> 
> 5: python arg.py test a b
> usage: arg.py [-h] method
> arg.py: error: unrecognized arguments: a b
> 
> 
> But for function test I guess I'm missing something, the idea is to
> have N functions and N param.
> 
> Any ideas?

You can either keep it simple and use sys.argv with

getattr(self, sys.argv[1])(*sys.argv[2:])

or you can have a look at subparsers. I took a stab at that:

$ cat automatic_subparsers.py
import argparse
import inspect

class Myclass(object):

    def foo(self):
        print 'foo'

    def bar(self):
        print 'bar'

    def test(self,name,place):
        print name, place

class Main(Myclass):
    def __init__(self):
        parser = argparse.ArgumentParser()
        subparsers = parser.add_subparsers()

        for name in dir(self):
            if not name.startswith("_"):
                p = subparsers.add_parser(name)
                method = getattr(self, name)
                argnames = inspect.getargspec(method).args[1:]
                for argname in argnames:
                    p.add_argument(argname)
                p.set_defaults(func=method, argnames=argnames)
        self.args = parser.parse_args()

    def __call__(self):
        a = self.args
        callargs = [getattr(a, name) for name in a.argnames]
        return self.args.func(*callargs)

if __name__ == "__main__":
    main = Main()

    main()
$ python automatic_subparsers.py -h
usage: automatic_subparsers.py [-h] {bar,foo,test} ...

positional arguments:
  {bar,foo,test}

optional arguments:
  -h, --help      show this help message and exit
$ python automatic_subparsers.py bar -h
usage: automatic_subparsers.py bar [-h]

optional arguments:
  -h, --help  show this help message and exit
$ python automatic_subparsers.py bar 
bar
$ python automatic_subparsers.py test -h
usage: automatic_subparsers.py test [-h] name place

positional arguments:
  name
  place

optional arguments:
  -h, --help  show this help message and exit
$ python automatic_subparsers.py test me here
me here

There may be a library out there that does this with bells and whistles, but 
I haven't looked.




More information about the Tutor mailing list