为什么调用 argparse.parse_args() 或 .parse_args(sys.argv) 时会有所不同
Why is there a difference when calling argparse.parse_args() or .parse_args(sys.argv)
我在 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 参数。路径参数必须在最后,并且错误在最后一个示例中有意义。
但是为什么它不关心第一个例子中的顺序?
编辑:我正在使用 python 版本 3.4.3
sys.argv
包含脚本名称作为第一项,即 myProgram.py
。该论点取代了 projectPath
。现在有一个额外的位置参数 /path/to/file
,它无法与任何参数匹配,因此出现错误。
不带参数调用 parse_args
ArgumentParser
足够聪明,可以忽略脚本名称进行解析。但是当显式传递一个参数数组时,它不能这样做并且会解析所有内容。
正如您在 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
时不包含脚本名称:
Beyond sys.argv
Sometimes it may be useful to have an ArgumentParser
parse arguments
other than those of sys.argv
. This can be accomplished by passing a
list of strings to parse_args()
. This is useful for testing at the
interactive prompt:
>>> 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
.
我在 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 参数。路径参数必须在最后,并且错误在最后一个示例中有意义。 但是为什么它不关心第一个例子中的顺序?
编辑:我正在使用 python 版本 3.4.3
sys.argv
包含脚本名称作为第一项,即 myProgram.py
。该论点取代了 projectPath
。现在有一个额外的位置参数 /path/to/file
,它无法与任何参数匹配,因此出现错误。
不带参数调用 parse_args
ArgumentParser
足够聪明,可以忽略脚本名称进行解析。但是当显式传递一个参数数组时,它不能这样做并且会解析所有内容。
正如您在 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
时不包含脚本名称:
Beyond
sys.argv
Sometimes it may be useful to have an
ArgumentParser
parse arguments other than those ofsys.argv
. This can be accomplished by passing a list of strings toparse_args()
. This is useful for testing at the interactive prompt:>>> 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
.