Python argparse 以不同的方式处理参数

Posted

技术标签:

【中文标题】Python argparse 以不同的方式处理参数【英文标题】:Python argparse treat arguments in different ways 【发布时间】:2014-11-10 10:10:34 【问题描述】:

我想创建一个可选参数,它将是'-- '(双破折号和一个空格)并将其后的所有内容作为其值。问题是在'-- ' 之后可能会出现一些其他可选参数。我不希望这些被解析为可选参数,而是'-- ' 的值。例如:

python prog1 --foo 1 --bar 2

这里foobar 是可选参数,其值分别为12

python prog1 --foo 1 --bar 2 -- --foo 4 --bar 14

在这里,我希望 '-- ' 之前的 foobar 被解析为可选参数。但我希望将'--foo 4 --bar 14' 解析为可选参数'-- ' 的值。如果可能的话,我想在不将'-- ' 之后的参数重命名为foo2bar2 的情况下执行此操作。

那么这可能吗?以及如何实施?

【问题讨论】:

为什么要这样做?这是一个完全的反模式,很可能只会让人们(/你未来的自己)感到困惑。 @will -- 这不是一个完整的反模式。这实际上是一种相对常见的方式来指定将传递给从属程序的参数(可能通过subprocess.Popen)。 @mgilson 所以我刚刚读到这个。这对我来说是个新闻。 事实上,argparse 已经支持使用-- 表示选项解析结束的通用约定。 -- 通常在类 Unix 操作系统上用于将参数与原始输入分开(通常原始输入表示要传递给某些 other 命令的参数,如xargs 的情况)。见unix.stackexchange.com/q/11376/4322。 【参考方案1】:

argparse 已经支持 -- 作为选项结束符。唯一的区别是默认处理单独处理以下参数。假设prog1 看起来像

import argparse

p = argparse.ArgumentParser()

p.add_argument('--foo')
p.add_argument('--bar')
p.add_argument('remaining', nargs=argparse.REMAINDER)

print p.parse_args()

然后是命令

% python prog1 --foo 1 --bar 2 -- --foo 4 --bar 14

生产

Namespace(bar='2', foo='1', remaining=['--', '--foo', '4', '--bar', '14'])

(而不是Namespace(..., remaining='-- --foo 4 --bar 14'))。如有必要,可以通过快速的后处理步骤来修复:

args = p.parse_args()
args.remaining = " ".join(args.remaining)
print args

那么结果就是

Namespace(bar='2', foo='1', remaining='-- --foo 4 --bar 14')

丢弃-- 参数需要一些额外的后处理:

args = p.parse_args()
if args.remaining[0] == "--":
    args = args[1:]

【讨论】:

这太棒了——但是,我似乎在文档中找不到它。我能找到的最接近的是argparse.REMAINDER,但这似乎没有使用-- 分隔符... 查看section 15.4.4.3 的最后(链接到文档的 Python 2.7 版本)。 谢谢你提醒我REMAINDER;这似乎是比* 更好的选择(至少更具描述性;我不知道在这种情况下是否存在功能差异。) 不错。好吧,无论如何,你有我的 +1 - 我学到了一些新东西。 我运行了这段代码,剩下的就是remaining=['--', '--foo', '4', '--bar', '14']。注意-- 出现在其余部分。【参考方案2】:

看起来docopt 库可以为您做到这一点;

来自usage-pattern-format 部分:

“[--]”。双破折号“--”按惯例用于分隔位置 可能被误认为是选项的参数。为了支持这个 约定将“[--]”添加到您的使用模式中。

【讨论】:

以上是关于Python argparse 以不同的方式处理参数的主要内容,如果未能解决你的问题,请参考以下文章

Python3 覆盖 argparse 错误

使用来自另一个脚本的参数启动 python 脚本,以编程方式设置 argparse 值

Python argparse库简单入门

如何将 argparse 参数传递给类

如何创建 Python 命名空间(argparse.parse_args 值)?

ArgParse Python 模块:更改继承参数的默认参数值