Cause Python's argparse to execute action for default

前端 未结 2 2040
旧时难觅i
旧时难觅i 2021-02-19 06:50

I am using argparse\'s action to add various data to a class. I would like to use that action on the default value if that arg is not provided at the command line. Is this possi

2条回答
  •  长情又很酷
    2021-02-19 07:33

    I needed to prompt the user if an option was not specified - that's how I did it:

    class _PromptUserAction(argparse.Action):
    
        def __call__(self, parser, namespace, values, option_string=None):
            if values == self.default:
                print 'Please specify', self.dest
                values = raw_input('>')
            setattr(namespace, self.dest, values)
    
    class Parser:
        def __init__(self, desc, add_h=True):
            self.parser = argparse.ArgumentParser(description=desc, add_help=add_h,
                            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
            #actions to be run on options if not specified (using default to check)
            self.actions = []
    
        @staticmethod
        def new(description, add_help=True):
            return Parser(description, add_help)
    
        # ...
    
        def milestone(self, help_='Specify the milestone for latest release.'):
            action = self.parser.add_argument('-m', '--milestone',
                                              dest='milestone',
                                              action=_PromptUserAction,
                                              default='PROMPT', # needed I think
                                              type=str,
                                              help=help_)
            self.actions.append(action)
            return self
    
        def parse(self):
            """
            Return an object which can be used to get the arguments as in:
                parser_instance.parse().milestone
    
            :return: ArgumentParser
            """
            args = self.parser.parse_args()
            # see: http://stackoverflow.com/a/21588198/281545
            dic = vars(args)
            ns = argparse.Namespace()
            for a in self.actions:
                if dic[a.dest] == a.default:
                    a(self.parser, ns, a.default) # call action
            # duh - can I avoid it ?
            import sys
            return self.parser.parse_args(sys.argv[1:],ns)
    

    I am interested if this can somehow be done without having to reparse the args (the import sys part). Maybe some constructor options for argparse.Action ?

提交回复
热议问题