Python argparse多个metavar名称

时间:2018-06-21 09:53:39

标签: python argparse

我正在使用python中的argparse库。在某些时候,我使用一个名为param的参数,它带有2个参数:一个键和一个值。我使用的代码行如下:

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

名称“键值”重复两次。我尝试使用列表和生成器,但发现的唯一方法是创建一个包含不同值的小类,并在向__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这样的临时类非常丑陋,而且我觉得必须有另一种(更好)的方式来做到这一点。我做对了吗?

2 个答案:

答案 0 :(得分:5)

通过深入滚动doc,我找到了答案

  

不同的nargs值可能会导致metavar被多次使用   次。向metavar提供元组可为   每个参数:

实际上,这工作得很好:

parser.add_argument("-p", "--param", nargs=2, action="append", 
                    help="key and value for query parameters",
                    type=str, metavar=("key", "value")
                    )

答案 1 :(得分:1)

metavar处理程序并不是特别复杂,但是确实利用了dataframe.to_csv(file, sep='|')类提供的信息。

关于您的班级为什么运作的原因并不明显,所以我研究了代码。

元数据在Formatter类中使用以下方法处理:

# Create some data and plot
library(tidyverse)
p <- as.data.frame(matrix(rnorm(20), ncol = 2, 
                     dimnames = list(1:10, c("x", "y")))) %>%
  mutate(group = as.factor(round((mean(y) - y)^2))) %>%
  ggplot(aes(x, y, color = group)) +
  geom_point() +
  theme_bw()

# you can't write it as txt or csv:
glimpse(p)

#List of 9
# $ data       :'data.frame':   10 obs. of  3 variables:
#  ..$ x    : num [1:10] -0.612 0.541 1.038 0.435 -0.317 ...
#  ..$ y    : num [1:10] 0.2065 0.9322 0.0485 -0.3972 -0.048 ...
#  ..$ group: Factor w/ 3 levels "0","1","2": 1 1 1 2 1 1 3 1 3 1
# $ layers     :List of 1

# but you can write it as Rds
write_rds(p, "./myplot.Rds")
# and read and plot afterwards:
read_rds("./myplot.Rds")

tuple

使用您的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

使用元组metavar:

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'