Python,argparse:如何让nargs=2的type=str和type=in

2024-05-15 18:13:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我花了一些时间在argparse文档上,但是我仍然在为程序中的一个选项而与这个模块斗争:

parser.add_argument("-r", "--rmsd", dest="rmsd", nargs=2,
    help="extract the poses that are close from a ref according RMSD",
    metavar=("ref","rmsd"))

我希望第一个参数是一个字符串(类型str)并且是必需的,而第二个参数应该具有类型int,如果没有给定值,则具有默认值(例如default=50)。我知道在只有一个参数的情况下该怎么做,但我不知道当nargs=2时该怎么做。。。有可能吗?


Tags: 模块文档程序refaddparser类型参数
2条回答

我倾向于同意迈克的解决办法,但这里有另一种方法。这并不理想,因为usage/help字符串告诉用户使用一个或多个参数。

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

这样,你就可以:

>>> 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

我建议使用两个参数:

import argparse

parser = argparse.ArgumentParser(description='Example with to arguments.')

parser.add_argument('-r', '--ref', dest='reference', required=True,
                    help='be helpful')
parser.add_argument('-m', '--rmsd', type=int, dest='reference_msd',
                    default=50, help='be helpful')

args = parser.parse_args()
print args.reference
print args.reference_msd

相关问题 更多 >