python - 互斥参数抱怨操作索引
python - mutually exclusive arguments complains about action index
我正在尝试对参数进行分组,以便用户可以执行以下任一操作:
python sample.py scan -a 1 -b 2
or
python sample.pt save -d /tmp -n something
这是我的代码:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
parser.add_argument('op', choices=['scan','save'], help='operation', default='scan')
root_group = parser.add_mutually_exclusive_group()
group1 = root_group.add_argument_group('g1', 'scan')
group1.add_argument('-a', help='dir1')
group1.add_argument('-b', help='dir2')
group2 = root_group.add_argument_group('g2', 'save')
group2.add_argument('-d', help='dir')
group2.add_argument('-n', help='name')
args = parser.parse_args()
print args
我运行 python sample.py --help
我遇到了一个错误。有人可以告诉我如何解决吗?
Traceback (most recent call last):
File "sample.py", line 18, in <module>
args = parser.parse_args()
File "C:\Python27\lib\argparse.py", line 1688, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "C:\Python27\lib\argparse.py", line 1720, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "C:\Python27\lib\argparse.py", line 1926, in _parse_known_args
start_index = consume_optional(start_index)
File "C:\Python27\lib\argparse.py", line 1866, in consume_optional
take_action(action, args, option_string)
File "C:\Python27\lib\argparse.py", line 1794, in take_action
action(self, namespace, argument_values, option_string)
File "C:\Python27\lib\argparse.py", line 994, in __call__
parser.print_help()
File "C:\Python27\lib\argparse.py", line 2313, in print_help
self._print_message(self.format_help(), file)
File "C:\Python27\lib\argparse.py", line 2287, in format_help
return formatter.format_help()
File "C:\Python27\lib\argparse.py", line 279, in format_help
help = self._root_section.format_help()
File "C:\Python27\lib\argparse.py", line 209, in format_help
func(*args)
File "C:\Python27\lib\argparse.py", line 317, in _format_usage
action_usage = format(optionals + positionals, groups)
File "C:\Python27\lib\argparse.py", line 388, in _format_actions_usage
start = actions.index(group._group_actions[0])
IndexError: list index out of range
如果我添加 action='store_const',错误就会消失,并且会出现一个新的错误,要求输入 4 个输入。
Argparse
似乎不完全支持将一个组添加到另一个组中。发生此错误是因为 Argparse
需要 root_group
进行某种操作。解决方法是向组中添加一个参数:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
# This is now redundant. We can remove it
# parser.add_argument('op', choices=['scan','save'], help='operation', default='scan')
root_group = parser.add_mutually_exclusive_group()
# Workaround
root_group.add_argument('--scan', help='scan', action='store_true')
root_group.add_argument('--save', help='save', action='store_true')
group1 = root_group.add_argument_group('g1', 'scan')
group2 = root_group.add_argument_group('g2', 'save')
group1.add_argument('-a', help='dir1')
group1.add_argument('-b', help='dir2')
group2.add_argument('-d', help='dir', default='')
group2.add_argument('-n', help='name')
args = parser.parse_args()
print args
请注意,我们使用的是 --scan
和 --save
。要避免使用 --
前缀,您可能需要 Sub-commands
的帮助。详情可见here.
多亏了@skyline 上面的 link,我让它与子解析器一起工作:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
scan_parser = argparse.ArgumentParser(add_help=False)
scan_parser.add_argument('-a', '--a', help='first num', required=True)
scan_parser.add_argument('-b', '--b', help='second num', required=True)
save_parser = argparse.ArgumentParser(add_help=False)
save_parser.add_argument('-d', '--d', help='directory path', required=True)
save_parser.add_argument('-n', '--n', help='name of the file', required=True)
sp = parser.add_subparsers()
sp_scan = sp.add_parser('scan', parents=[scan_parser], help='scans directories')
sp_save = sp.add_parser('save', parents=[save_parser], help='saves something')
args = parser.parse_args()
print args
格式化 usage
行时发生错误,这是 root_group
没有任何 _group_actions
的结果。我从其他错误问题中知道使用格式化程序很脆弱。
argument_groups
和 mutually_exclusive_groups
不是为了嵌套而设计的。尽管名称相似(和 class 传统),但它们的用途却截然不同。 argument_groups
控制 help
行的显示。 mutually_exclusive_groups
控制用法显示,并引发错误。
在你的例子中,添加到 group1
和 group2
的参数添加到主解析器列表,但没有添加到 root_group
用于排他性检查的列表(或使用格式)。
如果我直接向 root_group
添加参数,help
有效,并生成:
In [19]: parser.print_help()
usage: ipython3 [-h] [-a A] [-b B] [-d D] [-n N] [--foo FOO] {scan,save}
this is the description
positional arguments:
{scan,save} operation
optional arguments:
-h, --help show this help message and exit
--foo FOO
您可以从 'related' 侧边栏中看到,许多人询问过如何向 mutually_exclusive_groups
添加参数组。允许具有各种逻辑条件的嵌套组的补丁在未来还有很长的路要走。
但是,正如您发现的那样,子解析器机制可以很好地处理您的特定情况。
你不需要使用parents
机制:
sp = parser.add_subparsers()
sp_scan = sp.add_parser('scan', help='scans directories')
sp_scan.add_argument('-a', '--a', help='first num', required=True)
sp_scan.add_argument('-b', '--b', help='second num', required=True)
sp_save = sp.add_parser('save', parents=[save_parser], help='saves something')
sp_save.add_argument('-d', '--d', help='directory path', required=True)
sp_save.add_argument('-n', '--n', help='name of the file', required=True)
parents
机制在这里起作用,但更适用于解析器在别处定义(并导入)或在多个子解析器中重用的情况。例如,如果您有许多共享一组核心参数(以及它们自己独特的参数)的子解析器。
我正在尝试对参数进行分组,以便用户可以执行以下任一操作:
python sample.py scan -a 1 -b 2
or
python sample.pt save -d /tmp -n something
这是我的代码:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
parser.add_argument('op', choices=['scan','save'], help='operation', default='scan')
root_group = parser.add_mutually_exclusive_group()
group1 = root_group.add_argument_group('g1', 'scan')
group1.add_argument('-a', help='dir1')
group1.add_argument('-b', help='dir2')
group2 = root_group.add_argument_group('g2', 'save')
group2.add_argument('-d', help='dir')
group2.add_argument('-n', help='name')
args = parser.parse_args()
print args
我运行 python sample.py --help
我遇到了一个错误。有人可以告诉我如何解决吗?
Traceback (most recent call last):
File "sample.py", line 18, in <module>
args = parser.parse_args()
File "C:\Python27\lib\argparse.py", line 1688, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "C:\Python27\lib\argparse.py", line 1720, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "C:\Python27\lib\argparse.py", line 1926, in _parse_known_args
start_index = consume_optional(start_index)
File "C:\Python27\lib\argparse.py", line 1866, in consume_optional
take_action(action, args, option_string)
File "C:\Python27\lib\argparse.py", line 1794, in take_action
action(self, namespace, argument_values, option_string)
File "C:\Python27\lib\argparse.py", line 994, in __call__
parser.print_help()
File "C:\Python27\lib\argparse.py", line 2313, in print_help
self._print_message(self.format_help(), file)
File "C:\Python27\lib\argparse.py", line 2287, in format_help
return formatter.format_help()
File "C:\Python27\lib\argparse.py", line 279, in format_help
help = self._root_section.format_help()
File "C:\Python27\lib\argparse.py", line 209, in format_help
func(*args)
File "C:\Python27\lib\argparse.py", line 317, in _format_usage
action_usage = format(optionals + positionals, groups)
File "C:\Python27\lib\argparse.py", line 388, in _format_actions_usage
start = actions.index(group._group_actions[0])
IndexError: list index out of range
如果我添加 action='store_const',错误就会消失,并且会出现一个新的错误,要求输入 4 个输入。
Argparse
似乎不完全支持将一个组添加到另一个组中。发生此错误是因为 Argparse
需要 root_group
进行某种操作。解决方法是向组中添加一个参数:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
# This is now redundant. We can remove it
# parser.add_argument('op', choices=['scan','save'], help='operation', default='scan')
root_group = parser.add_mutually_exclusive_group()
# Workaround
root_group.add_argument('--scan', help='scan', action='store_true')
root_group.add_argument('--save', help='save', action='store_true')
group1 = root_group.add_argument_group('g1', 'scan')
group2 = root_group.add_argument_group('g2', 'save')
group1.add_argument('-a', help='dir1')
group1.add_argument('-b', help='dir2')
group2.add_argument('-d', help='dir', default='')
group2.add_argument('-n', help='name')
args = parser.parse_args()
print args
请注意,我们使用的是 --scan
和 --save
。要避免使用 --
前缀,您可能需要 Sub-commands
的帮助。详情可见here.
多亏了@skyline 上面的 link,我让它与子解析器一起工作:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='this is the description'
)
scan_parser = argparse.ArgumentParser(add_help=False)
scan_parser.add_argument('-a', '--a', help='first num', required=True)
scan_parser.add_argument('-b', '--b', help='second num', required=True)
save_parser = argparse.ArgumentParser(add_help=False)
save_parser.add_argument('-d', '--d', help='directory path', required=True)
save_parser.add_argument('-n', '--n', help='name of the file', required=True)
sp = parser.add_subparsers()
sp_scan = sp.add_parser('scan', parents=[scan_parser], help='scans directories')
sp_save = sp.add_parser('save', parents=[save_parser], help='saves something')
args = parser.parse_args()
print args
格式化 usage
行时发生错误,这是 root_group
没有任何 _group_actions
的结果。我从其他错误问题中知道使用格式化程序很脆弱。
argument_groups
和 mutually_exclusive_groups
不是为了嵌套而设计的。尽管名称相似(和 class 传统),但它们的用途却截然不同。 argument_groups
控制 help
行的显示。 mutually_exclusive_groups
控制用法显示,并引发错误。
在你的例子中,添加到 group1
和 group2
的参数添加到主解析器列表,但没有添加到 root_group
用于排他性检查的列表(或使用格式)。
如果我直接向 root_group
添加参数,help
有效,并生成:
In [19]: parser.print_help()
usage: ipython3 [-h] [-a A] [-b B] [-d D] [-n N] [--foo FOO] {scan,save}
this is the description
positional arguments:
{scan,save} operation
optional arguments:
-h, --help show this help message and exit
--foo FOO
您可以从 'related' 侧边栏中看到,许多人询问过如何向 mutually_exclusive_groups
添加参数组。允许具有各种逻辑条件的嵌套组的补丁在未来还有很长的路要走。
但是,正如您发现的那样,子解析器机制可以很好地处理您的特定情况。
你不需要使用parents
机制:
sp = parser.add_subparsers()
sp_scan = sp.add_parser('scan', help='scans directories')
sp_scan.add_argument('-a', '--a', help='first num', required=True)
sp_scan.add_argument('-b', '--b', help='second num', required=True)
sp_save = sp.add_parser('save', parents=[save_parser], help='saves something')
sp_save.add_argument('-d', '--d', help='directory path', required=True)
sp_save.add_argument('-n', '--n', help='name of the file', required=True)
parents
机制在这里起作用,但更适用于解析器在别处定义(并导入)或在多个子解析器中重用的情况。例如,如果您有许多共享一组核心参数(以及它们自己独特的参数)的子解析器。