【问题标题】:Why is there a difference when calling argparse.parse_args() or .parse_args(sys.argv)为什么调用 argparse.parse_args() 或 .parse_args(sys.argv) 时会有区别
【发布时间】:2015-07-06 21:54:37
【问题描述】:

我在我的 python 代码中创建了以下参数解析器。

parser = argparse.ArgumentParser()
parser.add_argument('projectPath')
parser.add_argument('-project')
parser.add_argument('-release')
parser.add_argument('--test', default=False, action='store_true')
args = parser.parse_args()

我正在按照以下方式执行我的程序。

myProgram.py /path/to/file -project super --test

如果我将上面的 sysntax 与

一起使用,它可以正常工作
args = parser.parse_args()

但是,如果我使用 sys.argv 作为输入

args = parser.parse_args(sys.argv)

解析器突然对参数的顺序很挑剔,我得到了无法识别的参数错误。

usage: fbu.py [-h] [-project PROJECT] [-release RELEASE] [--test] projectPath
fbu.py: error: unrecognized arguments: /path/to/file

正如我从错误中看到的,也使用了 -h 参数。 path 参数必须是最后一个,并且错误在最后一个示例中是有意义的。 但是为什么它不关心第一个示例中的顺序?

编辑:我使用的是 python 3.4.3 版

【问题讨论】:

  • 试试parser.parse_args(sys.argv[1:])
  • sys.argv[0] 用作默认的prog - 程序名称。

标签: python python-3.x argparse


【解决方案1】:

sys.argv 包含脚本名称作为第一项,即myProgram.py。该论点取代了projectPath。现在有一个额外的位置参数/path/to/file,它无法与任何参数匹配,因此出现错误。

在不带参数的情况下调用parse_args ArgumentParser 足够聪明,可以忽略解析的脚本名称。但是当显式传递一个参数数组时,它不能这样做并且会解析所有内容。

【讨论】:

  • 啊,我明白了。谢谢你。显然我没有很好地阅读文档。
【解决方案2】:

正如您从 the source code 中看到的 parse_known_args(由 parse_args 调用):

if args is None:
    # args default to the system args
    args = _sys.argv[1:]

当您没有显式提供参数时,Python 会从 .argv(即脚本的名称)中删除第一项。如果您手动传递参数,则必须自己执行此操作:

parser.parse_args(sys.argv[1:])

这在文档中没有明确介绍,但请注意 this section 在手动调用 parse_args 时不包含脚本名称:

超越sys.argv

有时使用ArgumentParser 解析参数可能很有用 sys.argv 的除外。这可以通过传递一个 parse_args() 的字符串列表。这对于在 互动提示:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...     'integers', metavar='int', type=int, choices=xrange(10),
...  nargs='+', help='an integer in the range 0..9')
>>> parser.add_argument(
...     '--sum', dest='accumulate', action='store_const', const=sum,
...   default=max, help='sum the integers (default: find the max)')
>>> parser.parse_args(['1', '2', '3', '4'])
Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
>>> parser.parse_args('1 2 3 4 --sum'.split())
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

手动传递参数的优点是它可以更轻松地测试解析功能,因为您可以传递适当参数的列表,而不是尝试修补 sys.argv

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 2015-12-17
    • 2018-06-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 2013-12-04
    相关资源
    最近更新 更多