Python,argparse:如何使 nargs=2 与 type=str 和 type=int
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16959101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python,argparse: how to have nargs=2 with type=str and type=int
提问by Bux31
I spent some times on the argparse documentation, but I'm still struggling with this module for one option in my program:
我花了一些时间在 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"))
I'd like to the first argument to be a string (type str) and mandatory, while the second argument should have type int, and if no value is given have a default one (let's say default=50). I know how to do that when there is only one argument expected, but I have no idea how to proceed when nargs=2... Is that even possible?
我希望第一个参数是字符串(type str)并且是强制性的,而第二个参数应该有 type int,如果没有给出值,则有一个默认值(比方说default=50)。我知道当只有一个参数时该怎么做,但是当 nargs=2 时我不知道如何继续......这可能吗?
回答by Mike Müller
I would recommend using two arguments:
我建议使用两个参数:
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
回答by ashokadhikari
You can do the following. The requiredkeyword sets the field mandatory and the default=50sets the default value of the option to 50 if not specified:
您可以执行以下操作。该required关键字设置强制性领域和default=50将选项设置为50的默认值,如果没有指定:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--string", type=str, required=True)
parser.add_argument("-i", "--integer", type=int, default=50)
args = parser.parse_args()
print args.string
print args.integer
Output:
输出:
$ python arg_parser.py -s test_string
test_string
50
$ python arg_parser.py -s test_string -i 100
test_string
100
$ python arg_parser.py -i 100
usage: arg_parser.py [-h] -s STRING [-i INTEGER]
arg_parser.py: error: argument -s/--string is required
回答by ashokadhikari
I tend to agree with Mike's solution, but here's another way. It's not ideal, since the usage/help string tells the user to use 1 or more arguments.
我倾向于同意迈克的解决方案,但这是另一种方式。这并不理想,因为用法/帮助字符串告诉用户使用 1 个或多个参数。
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 that, 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
回答by Grant Mills
Sorry for jumping in way late. I'd use a function for type to call.
抱歉迟到了。我会使用一个函数来调用类型。
def two_args_str_int(x):
try:
return int(x)
except:
return x
parser.add_argument("-r", "--rmsd", dest="rmsd", nargs=2, type=two_args_str_int
help="extract the poses that are close from a ref according RMSD",
metavar=("ref","rmsd"))
回答by MarSoft
I had a similar problem, but "use two arguments" approach didn't work for me because I need a list of pairs: parser.add_argument('--replace', nargs=2, action='append')and if I use separate arguments then I would have to validate lengths of lists etc.
Here is what I did:
我有一个类似的问题,但“使用两个参数”方法对我不起作用,因为我需要一个对列表:parser.add_argument('--replace', nargs=2, action='append')如果我使用单独的参数,那么我将不得不验证列表的长度等。这是我所做的:
- Use
tupleformetavarto properly show help:tuple=('OLD', 'NEW')results in the help string being displayed as--replace OLD NEW. It is documented but I could not find it until tried different options. - Use custom validation: after
parse_args, validate the resulting list's items and callparser.error()if something is wrong. That's because they have different data types.
- 使用
tuple了metavar正确显示的帮助:tuple=('OLD', 'NEW')在帮助字符串结果被显示为--replace OLD NEW。它被记录在案,但在尝试不同的选项之前我找不到它。 - 使用自定义验证: after
parse_args,验证结果列表的项目并在出现问题时调用parser.error()。那是因为它们具有不同的数据类型。

