Python3 Argparse 可选位置参数
Python3 Argparse optional positional argument
目前,当我尝试 运行 我在 argparse 中的一个选项时,我必须先写一些东西,例如:
python3 main.py https://example.com ping-history
这适用于我的其他选项(ping 和其他选项),因为我需要指定要访问的网站。但是我需要它来为我的一个选项破例。
所以它看起来像这样:
python3 main.py ping-history
我试过添加:
nargs="?"
至:
parser.add_argument('filename', help="input file")
这解决了问题,但是当我尝试 运行 --verbose 或 --silent:
python3 main.py https://example.com -v title
我明白了:
main.py: error: argument commands: invalid choice: 'https://example.com'
我不确定发生了什么,有人可以解释一下吗?
编辑:解析器文件:
import argparse
VERSION = "v1.0.0 (2017-06-16)"
def add_options(parser):
"""add options"""
group = parser.add_mutually_exclusive_group()
group.add_argument("-s", "--silent", dest="silent", help="Less output", action="store_true")
group.add_argument("-v", "--verbose", dest="verbose", help="More output", action="store_true")
parser.add_argument("-V", "--version", action="version", version=VERSION)
parser.add_argument('filename', help="input file", nargs="?")
def add_commands(parser):
"""Adds commands"""
subparser = parser.add_subparsers(title="commands (positional arguments)", help="Available commands",\
dest="commands")
subparser.add_parser("lines", help="count lines in textfile")
subparser.add_parser("words", help="count words in textfile")
subparser.add_parser("letters", help="count letters in textfile")
subparser.add_parser("all", help="count all")
subparser.add_parser("word_frequency", help="count word frequency")
subparser.add_parser("letter_frequency", help="count letter frequency")
#subparser.add_parser("filename", help= "filename to analyze")
subparser.add_parser("ping", help="ping a website")
subparser.add_parser("ping-history", help="show past status code")
subparser.add_parser("quote", help="retrieve todays quote")
subparser.add_parser("title", help="retrive titel from page")
def parse_options():
"""add options"""
parser = argparse.ArgumentParser()
add_options(parser)
add_commands(parser)
arg, unknown_args = parser.parse_known_args()
options = {}
options["known_args"] = vars(arg)
options["unknown_args"] = unknown_args
return options
在我的评论中,我猜你有一个可选的位置最后。但进一步思考你的错误与初始可选位置更一致。
In [42]: parser=argparse.ArgumentParser()
In [43]: a1 = parser.add_argument('name');
In [44]: parser.add_argument('-v',action='store_true');
In [45]: parser.add_argument('cmds',choices=['one','two'])
In [46]: parser.parse_args('foo one'.split())
Out[46]: Namespace(cmds='one', name='foo', v=False)
In [47]: parser.parse_args('foo -v one'.split())
Out[47]: Namespace(cmds='one', name='foo', v=True)
将第一个参数更改为可选参数:
In [48]: a1.nargs
In [49]: a1.nargs='?'
In [50]: parser.parse_args('foo one'.split())
Out[50]: Namespace(cmds='one', name='foo', v=False)
In [51]: parser.parse_args('foo -v one'.split())
usage: ipython3 [-h] [-v] [name] {one,two}
ipython3: error: argument cmds: invalid choice: 'foo' (choose from 'one', 'two')
...
如果我只给它一个字符串,我会得到同样的错误:
In [54]: parser.parse_args('foo'.split())
usage: ipython3 [-h] [-v] [name] {one,two}
ipython3: error: argument cmds: invalid choice: 'foo'
parse_args
在评估位置和可选之间交替。在进行定位时,它会尝试处理尽可能多的字符串(使用 regex
样式模式匹配)。一种 '?' positional 可以匹配空字符串。因此,当它只看到一个字符串 'foo' 时,它会将 []
与 'name' 进行匹配,并尝试将 'foo' 与 'cmd'.
进行匹配
有bug/issues关于使解析看起来更远,并预期第二个位置可能满足标志后的字符串。但是现在,当一个或多个位置是 'optional'.
时,不要混合标志和位置
In [55]: parser.parse_args('foo one -v'.split())
Out[55]: Namespace(cmds='one', name='foo', v=True)
In [56]: parser.parse_args('-v foo one'.split())
Out[56]: Namespace(cmds='one', name='foo', v=True)
编辑
在您的完整解析器中,第二个 positional
是子解析器。正如我在上面演示的那样,它尝试将 ['https://example.com']
应用于两个 '?'参数和子解析器。
所以工作调用是:
python3 main.py -v https://example.com title
如果 commands
中只有一部分需要 filename
,请考虑将该参数分配给那些子解析器,而不是使其成为父解析器的可选参数。
一般来说,父位置在使用子解析器时很棘手。标记所有父参数更容易。
目前,当我尝试 运行 我在 argparse 中的一个选项时,我必须先写一些东西,例如:
python3 main.py https://example.com ping-history
这适用于我的其他选项(ping 和其他选项),因为我需要指定要访问的网站。但是我需要它来为我的一个选项破例。 所以它看起来像这样:
python3 main.py ping-history
我试过添加:
nargs="?"
至:
parser.add_argument('filename', help="input file")
这解决了问题,但是当我尝试 运行 --verbose 或 --silent:
python3 main.py https://example.com -v title
我明白了:
main.py: error: argument commands: invalid choice: 'https://example.com'
我不确定发生了什么,有人可以解释一下吗?
编辑:解析器文件:
import argparse
VERSION = "v1.0.0 (2017-06-16)"
def add_options(parser):
"""add options"""
group = parser.add_mutually_exclusive_group()
group.add_argument("-s", "--silent", dest="silent", help="Less output", action="store_true")
group.add_argument("-v", "--verbose", dest="verbose", help="More output", action="store_true")
parser.add_argument("-V", "--version", action="version", version=VERSION)
parser.add_argument('filename', help="input file", nargs="?")
def add_commands(parser):
"""Adds commands"""
subparser = parser.add_subparsers(title="commands (positional arguments)", help="Available commands",\
dest="commands")
subparser.add_parser("lines", help="count lines in textfile")
subparser.add_parser("words", help="count words in textfile")
subparser.add_parser("letters", help="count letters in textfile")
subparser.add_parser("all", help="count all")
subparser.add_parser("word_frequency", help="count word frequency")
subparser.add_parser("letter_frequency", help="count letter frequency")
#subparser.add_parser("filename", help= "filename to analyze")
subparser.add_parser("ping", help="ping a website")
subparser.add_parser("ping-history", help="show past status code")
subparser.add_parser("quote", help="retrieve todays quote")
subparser.add_parser("title", help="retrive titel from page")
def parse_options():
"""add options"""
parser = argparse.ArgumentParser()
add_options(parser)
add_commands(parser)
arg, unknown_args = parser.parse_known_args()
options = {}
options["known_args"] = vars(arg)
options["unknown_args"] = unknown_args
return options
在我的评论中,我猜你有一个可选的位置最后。但进一步思考你的错误与初始可选位置更一致。
In [42]: parser=argparse.ArgumentParser()
In [43]: a1 = parser.add_argument('name');
In [44]: parser.add_argument('-v',action='store_true');
In [45]: parser.add_argument('cmds',choices=['one','two'])
In [46]: parser.parse_args('foo one'.split())
Out[46]: Namespace(cmds='one', name='foo', v=False)
In [47]: parser.parse_args('foo -v one'.split())
Out[47]: Namespace(cmds='one', name='foo', v=True)
将第一个参数更改为可选参数:
In [48]: a1.nargs
In [49]: a1.nargs='?'
In [50]: parser.parse_args('foo one'.split())
Out[50]: Namespace(cmds='one', name='foo', v=False)
In [51]: parser.parse_args('foo -v one'.split())
usage: ipython3 [-h] [-v] [name] {one,two}
ipython3: error: argument cmds: invalid choice: 'foo' (choose from 'one', 'two')
...
如果我只给它一个字符串,我会得到同样的错误:
In [54]: parser.parse_args('foo'.split())
usage: ipython3 [-h] [-v] [name] {one,two}
ipython3: error: argument cmds: invalid choice: 'foo'
parse_args
在评估位置和可选之间交替。在进行定位时,它会尝试处理尽可能多的字符串(使用 regex
样式模式匹配)。一种 '?' positional 可以匹配空字符串。因此,当它只看到一个字符串 'foo' 时,它会将 []
与 'name' 进行匹配,并尝试将 'foo' 与 'cmd'.
有bug/issues关于使解析看起来更远,并预期第二个位置可能满足标志后的字符串。但是现在,当一个或多个位置是 'optional'.
时,不要混合标志和位置In [55]: parser.parse_args('foo one -v'.split())
Out[55]: Namespace(cmds='one', name='foo', v=True)
In [56]: parser.parse_args('-v foo one'.split())
Out[56]: Namespace(cmds='one', name='foo', v=True)
编辑
在您的完整解析器中,第二个 positional
是子解析器。正如我在上面演示的那样,它尝试将 ['https://example.com']
应用于两个 '?'参数和子解析器。
所以工作调用是:
python3 main.py -v https://example.com title
如果 commands
中只有一部分需要 filename
,请考虑将该参数分配给那些子解析器,而不是使其成为父解析器的可选参数。
一般来说,父位置在使用子解析器时很棘手。标记所有父参数更容易。