Python 获取多个元变量名称
Python argparse multiple metavar names
我正在 python 中使用 argparse
库。有时,我使用一个名为 param
的参数,它有两个参数:一个键和一个值。我使用的代码行如下:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query",
type=str, metavar="key value"
)
这里有什么问题是我调用帮助时,它显示如下:
optional arguments:
-h, --help show this help message and exit
-p key value key value, --param key value key value
key and value for query parameters
名字'key value'重复了两次。我尝试使用列表和生成器,但我发现的唯一方法是创建一个包含不同值的小 class 并在询问 __str__
时生成它们,如下所示:
class Meta:
def __init__(self, iterable):
self.gene = itertools.cycle(iterable)
def __str__(self):
return self.gene.__next__()
我这样称呼 add_argument
:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query parameters",
type=str, metavar=Meta(["key", "value"])
)
并且正确显示:
-p key value, --param key value
key and value for query parameters
但我发现使用像 Meta
这样的临时 class 非常丑陋,我觉得必须有另一种(更好的)方法来做到这一点。我做对了吗?
通过深入滚动 doc,我找到了答案
Different values of nargs may cause the metavar to be used multiple
times. Providing a tuple to metavar specifies a different display for
each of the arguments:
的确,这工作得很好:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query parameters",
type=str, metavar=("key", "value")
)
元变量处理程序不是特别复杂,但确实利用了 tuple
class 提供的信息。
为什么你的 class 工作并不明显,所以我深入研究了代码。
Metavar 在 Formatter class 中处理:
def _metavar_formatter(self, action, default_metavar):
if action.metavar is not None:
result = action.metavar
elif action.choices is not None:
choice_strs = [str(choice) for choice in action.choices]
result = '{%s}' % ','.join(choice_strs)
else:
result = default_metavar
def format(tuple_size):
if isinstance(result, tuple):
return result
else:
return (result, ) * tuple_size
return format
和
def _format_args(self, action, default_metavar):
get_metavar = self._metavar_formatter(action, default_metavar)
....
else:
# for numeric nargs
formats = ['%s' for _ in range(action.nargs)]
result = ' '.join(formats) % get_metavar(action.nargs)
return result
所以你的 Meta
:
In [261]: x = Meta(['one', 'two'])
In [262]: x
Out[262]: <__main__.Meta at 0x7f36980f65c0>
In [263]: x = (x,)*2
In [264]: x
Out[264]: (<__main__.Meta at 0x7f36980f65c0>, <__main__.Meta at 0x7f36980f65c0>)
In [265]: '%s %s'%x
Out[265]: 'one two'
使用元组元变量:
In [266]: '%s %s'%('one','two')
Out[266]: 'one two'
并且只有一个字符串
In [267]: '%s %s'%(('one two',)*2)
Out[267]: 'one two one two'
我正在 python 中使用 argparse
库。有时,我使用一个名为 param
的参数,它有两个参数:一个键和一个值。我使用的代码行如下:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query",
type=str, metavar="key value"
)
这里有什么问题是我调用帮助时,它显示如下:
optional arguments:
-h, --help show this help message and exit
-p key value key value, --param key value key value
key and value for query parameters
名字'key value'重复了两次。我尝试使用列表和生成器,但我发现的唯一方法是创建一个包含不同值的小 class 并在询问 __str__
时生成它们,如下所示:
class Meta:
def __init__(self, iterable):
self.gene = itertools.cycle(iterable)
def __str__(self):
return self.gene.__next__()
我这样称呼 add_argument
:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query parameters",
type=str, metavar=Meta(["key", "value"])
)
并且正确显示:
-p key value, --param key value
key and value for query parameters
但我发现使用像 Meta
这样的临时 class 非常丑陋,我觉得必须有另一种(更好的)方法来做到这一点。我做对了吗?
通过深入滚动 doc,我找到了答案
Different values of nargs may cause the metavar to be used multiple times. Providing a tuple to metavar specifies a different display for each of the arguments:
的确,这工作得很好:
parser.add_argument("-p", "--param", nargs=2, action="append",
help="key and value for query parameters",
type=str, metavar=("key", "value")
)
元变量处理程序不是特别复杂,但确实利用了 tuple
class 提供的信息。
为什么你的 class 工作并不明显,所以我深入研究了代码。
Metavar 在 Formatter class 中处理:
def _metavar_formatter(self, action, default_metavar):
if action.metavar is not None:
result = action.metavar
elif action.choices is not None:
choice_strs = [str(choice) for choice in action.choices]
result = '{%s}' % ','.join(choice_strs)
else:
result = default_metavar
def format(tuple_size):
if isinstance(result, tuple):
return result
else:
return (result, ) * tuple_size
return format
和
def _format_args(self, action, default_metavar):
get_metavar = self._metavar_formatter(action, default_metavar)
....
else:
# for numeric nargs
formats = ['%s' for _ in range(action.nargs)]
result = ' '.join(formats) % get_metavar(action.nargs)
return result
所以你的 Meta
:
In [261]: x = Meta(['one', 'two'])
In [262]: x
Out[262]: <__main__.Meta at 0x7f36980f65c0>
In [263]: x = (x,)*2
In [264]: x
Out[264]: (<__main__.Meta at 0x7f36980f65c0>, <__main__.Meta at 0x7f36980f65c0>)
In [265]: '%s %s'%x
Out[265]: 'one two'
使用元组元变量:
In [266]: '%s %s'%('one','two')
Out[266]: 'one two'
并且只有一个字符串
In [267]: '%s %s'%(('one two',)*2)
Out[267]: 'one two one two'