【问题标题】:Using argparse to parse arguments of form "arg= val"使用 argparse 解析“arg= val”形式的参数
【发布时间】:2011-07-06 11:57:39
【问题描述】:

我想使用 argparse 来解析形式为“arg=val”的命令行 例如,用法是:

script.py conf_dir=/tmp/good_conf

为了实现它,我正在这样做:

desc   = "details"
parser = argparse.ArgumentParser(description=desc, add_help=False)
args = parser.add_argument("conf_dir")
args = parser.parse_args("conf_dir=FOO".split())
args = parser.parse_args()
print args.conf_dir

但是,问题在于,在调用脚本时:

python script.py conf_dir=/tmp/good_conf

我明白了:

conf_dir=/tmp/good_conf

我期待的地方

/tmp/good_conf

所以,问题是:我可以使用 argparse 来解析包含名称值对的 cmd 行吗? 有什么提示吗?

编辑:我想这样做而不是像 --conf_dir=/tmp/good_dir 这样的原因是因为有其他工具(用其他语言编写)使用 conf_dir=/tmp/good_dir 风格的参数。为了保持一致性,我将以这种方式解析 args。

【问题讨论】:

  • 我没有argparse 可以检查这个,但"conf_dir=FOO".split() 实际上不应该是"conf_dir=FOO".split('=')

标签: python parsing command-line argparse


【解决方案1】:

您需要一个自定义操作

class StoreNameValuePair(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        n, v = values.split('=', 1)
        setattr(namespace, n, v)

args = parser.add_argument("conf_dir", action=StoreNameValuePair)

【讨论】:

  • str.partition()str.split() 更不容易出现 ValueError,因为它总是返回三个项目。
  • 我宁愿用values.split('=', 1) 处理它,它不会不必要地返回=。可以说,如果名称值对实际上不是一对,您会想要 ValueError。 (尽管您是想捕捉错误——还是让它向上传播——或者检查 values.partition("=")[1] 是否为空,这可能是个人喜好问题。)
  • 好的,尽管.partition 主要是为这个用例而构建的。分隔符可以分配给_,也可以通过检查v是否为空来检查错误。一切都没有尝试除了。 ;-)
【解决方案2】:

根据the documentationargparse 本身不会让您拥有这样的无前缀选项。如果您省略前导 -,它假定您正在描述一个位置参数并期望它被提供为:

python script.py /tmp/good_conf

如果您希望它是可选的,则需要通过调用--conf_dir 将其正确标记为标志,并调用如下脚本:

python script.py --conf_dir=/tmp/good_conf

但是,要接受名称-值对,您可以实现 custom action。结合nargs,这样的动作可以接受任意数量的名称-值对并将它们存储在参数解析结果对象中。

【讨论】:

    【解决方案3】:

    @chepner 这太好了。我对此进行了改进以支持多个参数并将结果存储为字典:

    class StoreDict(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            kv={}
            if not isinstance(values, (list,)):
                values=(values,)
            for value in values:
                n, v = value.split('=')
                kv[n]=v
            setattr(namespace, self.dest, kv)
    

    【讨论】:

      【解决方案4】:

      在命令行上放置名称值对的常用方法是使用选项。 IE。你会使用

      python script.py --confdir=/tmp/good_conf
      

      argparse 当然可以处理这种情况。请参阅以下位置的文档:

      http://docs.python.org/library/argparse.html#option-value-syntax

      【讨论】:

        猜你喜欢
        • 2018-12-14
        • 2014-03-04
        • 1970-01-01
        • 1970-01-01
        • 2013-09-13
        • 1970-01-01
        • 2015-03-04
        • 2016-06-19
        相关资源
        最近更新 更多