argparse optional subparser (for --version)

前端 未结 7 1384
长情又很酷
长情又很酷 2020-12-09 03:38

I have the following code (using Python 2.7):

# shared command line options, like --version or --verbose
parser_shared = argparse.ArgumentParser(add_help=Fal         


        
7条回答
  •  盖世英雄少女心
    2020-12-09 04:30

    Although @eumiro's answer address the --version option, it can only do so because that is a special case for optparse. To allow general invocations of:

     prog
     prog --verbose
     prog --verbose main
     prog --verbose db 
    

    and have prog --version work the same as prog --verbose main (and prog main --verbose) you can add a method to Argumentparser and call that with the name of the default subparser, just before invoking parse_args():

    import argparse
    import sys
    
    def set_default_subparser(self, name, args=None):
        """default subparser selection. Call after setup, just before parse_args()
        name: is the name of the subparser to call by default
        args: if set is the argument list handed to parse_args()
    
        , tested with 2.7, 3.2, 3.3, 3.4
        it works with 2.6 assuming argparse is installed
        """
        subparser_found = False
        for arg in sys.argv[1:]:
            if arg in ['-h', '--help']:  # global help if no subparser
                break
        else:
            for x in self._subparsers._actions:
                if not isinstance(x, argparse._SubParsersAction):
                    continue
                for sp_name in x._name_parser_map.keys():
                    if sp_name in sys.argv[1:]:
                        subparser_found = True
            if not subparser_found:
                # insert default in first position, this implies no
                # global options without a sub_parsers specified
                if args is None:
                    sys.argv.insert(1, name)
                else:
                    args.insert(0, name)
    
    argparse.ArgumentParser.set_default_subparser = set_default_subparser
    
    def do_main(args):
        print 'main verbose', args.verbose
    
    def do_db(args):
        print 'db verbose:', args.verbose
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbose', action='store_true')
    parser.add_argument('--version', action='version', version='%(prog)s 2.0')
    subparsers = parser.add_subparsers()
    sp = subparsers.add_parser('main')
    sp.set_defaults(func=do_main)
    sp.add_argument('--verbose', action='store_true')
    sp = subparsers.add_parser('db')
    sp.set_defaults(func=do_db)
    
    parser.set_default_subparser('main')
    args = parser.parse_args()
    
    if hasattr(args, 'func'):
        args.func(args)
    

    The set_default_subparser() method is part of the ruamel.std.argparse package.

提交回复
热议问题