我们正在尝试通过我们正在使用的命令行工具构建一个包装脚本。我们想根据包装脚本中的选项设置一些工具参数。我们还希望有可能将原生参数直接传递给命令行工具,因为它们是在命令行上编写的。
这是我们想出的:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('positional')
parser.add_argument('-f', '--foo', action='store_true')
parser.add_argument('-b', '--bar', action='store_true')
parser.add_argument('native_arg', nargs='*')
args = parser.parse_args()
print (args)
Run Code Online (Sandbox Code Playgroud)
positional是强制性的。基于这些选项-f,-b我们会向我们的工具调用添加一些额外的选项。之后留下的任何东西(如果有的话)都应该被视为本机工具参数并直接提供给工具。调用我们的脚本-h产生以下用法:
usage: test.py [-h] [-f] [-b] positional [native_arg [native_arg ...]]
Run Code Online (Sandbox Code Playgroud)
诀窍是这些本机参数本身就是该工具的选项,并包含前导破折号,例如-native0和-native1。我们已经知道使用双破折号来阻止argparse寻找更多选项的技巧。以下调用:
./test.py pos -- -native0 -native1
Run Code Online (Sandbox Code Playgroud)
产生预期的解析参数:
Namespace(bar=False, foo=False, native_arg=['-native0', '-native1'], positional='pos')
Run Code Online (Sandbox Code Playgroud)
但是,尝试在第一个位置参数后添加选项不起作用。更具体地说,以下调用:
./test.py pos --foo -- -native0 -native1
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
usage: [...shortened...]
test.py: error: unrecognized arguments: -- -native0 -native1
Run Code Online (Sandbox Code Playgroud)
将可选参数放在位置之前:
./test.py --foo pos -- -native0 -native1
Run Code Online (Sandbox Code Playgroud)
似乎可以工作,因为打印了以下内容:
Namespace(bar=False, foo=True, native_arg=['-native0', '-native1'], positional='pos')
Run Code Online (Sandbox Code Playgroud)
更奇怪的是,改变的值nargs的native_arg,以'+'在所有上述情况作品(需要提醒的,当然,至少有一个native_arg预期)。
我们是在 Python 代码中做错了什么还是这是某种argparse错误?
argparse当您将非必需的位置参数与可选参数混合使用时,确实会遇到困难(有关错误报告的详细信息,请参阅/sf/answers/3304610781/)。我将提出一种替代方法,而不是提出解决此问题的方法。
您应该查看parse_known_args为您描述的情况创建的方法(即将选项传递给包装工具)。
In [1]: import argparse
In [2]: parser = argparse.ArgumentParser()
In [3]: parser.add_argument('positional')
In [4]: parser.add_argument('-f', '--foo', action='store_true')
In [5]: parser.add_argument('-b', '--bar', action='store_true')
In [6]: parser.parse_known_args(['pos', '--foo', '-native0', '-native1'])
Out[6]: (Namespace(bar=False, foo=True, positional='pos'), ['-native0', '-native1'])
Run Code Online (Sandbox Code Playgroud)
与 不同parse_args, 的输出parse_known_args是一个二元素元组。第一个元素是Namespace您希望从中获取的实例parse_args,它包含调用 定义的所有属性add_argument。第二个元素是解析器不知道的所有参数的列表。
我个人更喜欢这种方法,因为用户不需要记住任何关于如何调用你的程序的技巧,或者哪个选项顺序不会导致错误。
| 归档时间: |
|
| 查看次数: |
3415 次 |
| 最近记录: |