使用argparse解析"arg= val"格式的参数

22 投票
4 回答
11942 浏览
提问于 2025-04-16 12:44

我想用 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 来解析包含名称值对的命令行?有没有什么提示?

补充说明:我想这样做而不是用类似 --conf_dir=/tmp/good_dir 的方式,是因为还有其他工具(用其他语言写的)也使用 conf_dir=/tmp/good_dir 这种参数风格。为了保持一致性,我想以这种方式解析参数。

4 个回答

2

@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)
29

你需要一个自定义的操作

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

根据文档的说明,argparse这个库本身不支持没有前缀的选项。如果你不加前面的-,它会认为你在描述一个位置参数,并且期待你这样提供它:

python script.py /tmp/good_conf

如果你想让这个参数变成可选的,就需要正确地标记它为一个标志,比如叫它--conf_dir,然后像这样调用脚本:

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

不过,如果你想接受名称-值对,你可以实现一个自定义动作。结合nargs,这样的动作可以接受任意数量的名称-值对,并把它们存储在参数解析的结果对象中。

撰写回答