I tend to agree with Mike's decision, but here is another way. This is not ideal since the use / help line tells the user to use 1 or more arguments.
import argparse def string_integer(int_default): """Action for argparse that allows a mandatory and optional argument, a string and integer, with a default for the integer. This factory function returns an Action subclass that is configured with the integer default. """ class StringInteger(argparse.Action): """Action to assign a string and optional integer""" def __call__(self, parser, namespace, values, option_string=None): message = '' if len(values) not in [1, 2]: message = 'argument "{}" requires 1 or 2 arguments'.format( self.dest) if len(values) == 2: try: values[1] = int(values[1]) except ValueError: message = ('second argument to "{}" requires ' 'an integer'.format(self.dest)) else: values.append(int_default) if message: raise argparse.ArgumentError(self, message) setattr(namespace, self.dest, values) return StringInteger
And with this you get:
>>> import argparse >>> parser = argparse.ArgumentParser(description="") parser.add_argument('-r', '--rmsd', dest='rmsd', nargs='+', ... action=string_integer(50), ... help="extract the poses that are close from a ref " ... "according RMSD") >>> parser.parse_args('-r reference'.split()) Namespace(rmsd=['reference', 50]) >>> parser.parse_args('-r reference 30'.split()) Namespace(rmsd=['reference', 30]) >>> parser.parse_args('-r reference 30 3'.split()) usage: [-h] [-r RMSD [RMSD ...]] : error: argument -r/--rmsd: argument "rmsd" requires 1 or 2 arguments >>> parser.parse_args('-r reference 30.3'.split()) usage: [-h] [-r RMSD [RMSD ...]] : error: argument -r/--rmsd: second argument to "rmsd" requires an integer
user707650
source share