python argparse store --foo=bar as args.key='foo', args.value='bar'

前端 未结 2 997
猫巷女王i
猫巷女王i 2021-01-23 13:59

I\'d like to parse a command line that has a mutually exclusive group of options. Normally, I\'d just use --foo bar which would produce, in the namespace, ar

2条回答
  •  粉色の甜心
    2021-01-23 14:42

    As I understand it, you would like to be able to specify a composite action so that you both save the option name used in one Namespace slot and have the updates for some other action performed. E.g., you want to be able to write something like:

    group = argparse.mutually_exclusive_group()
    group.add_argument('--foo', action=StoreOption, subaction='store_true')
    group.add_argument('--bar', nargs='?', action=StoreOption, subaction='store')
    

    The action class is StoreOption, but it will call the action specified by subaction to perform additional updates to the Namespace object.

    The code I got working (with very limited testing) is shown below:

    import argparse
    
    class StoreOption(argparse.Action):
      def __init__(self, **kwargs):
        kwargs['action'] = kwargs.pop('subaction')
        container = kwargs.pop('container')
    
        action_class = container._pop_action_class(kwargs)
        if not callable(action_class):
          raise ValueError('unknown action "%s"' % (action_class,))
    
        kwargs['dest'] = 'thing'
        self._action = action_class(**kwargs)
        print "_action:", self._action
    
        super(StoreOption, self).__init__(
            option_strings= self._action.option_strings,
            dest= self._action.dest,
            nargs= self._action.nargs,
            const= self._action.const,
            default= self._action.default,
            type= self._action.type,
            choices= self._action.choices,
            required= self._action.required,
            help= self._action.help,
            metavar= self._action.metavar)
    
      def __call__(self, parser, namespace, values, option_string=None):
        print "got here:", option_string, namespace
        setattr(namespace, 'key', option_string)
        self._action(parser, namespace, values, option_string)
    

    A test:

    parser = argparse.ArgumentParser(prog='PROG')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--foo', container=group, action=StoreOption, subaction='store_true')
    group.add_argument('--bar', container=group, nargs=2, action=StoreOption, subaction='store')
    
    print parser.parse_args(['--bar', 'asd', 'qwe'])
    -- prints: Namespace(key='--bar', thing=['asd', 'qwe'])
    

    Basically StoreOption is an Action which wraps another Action (the one specified by subaction). When adding arguments you need to pass the container= parameter so that it can construct the sub-action. Also, there is some fiddling with the keyword arguments to set them up correctly for the sub-action.

    Again, this has undergone very limited testing, so it may not work for all sub-actions, but it should point you in the right direction.

提交回复
热议问题