Disable/Remove argparse 中的参数
Disable/Remove argument in argparse
是否可以删除或禁用 argparse 中的参数,使其不显示在帮助中?怎么样?
添加新参数很容易:
parser = argparse.ArgumentParser()
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
而且我知道您可以通过指定 "resolve" 冲突处理程序来使用新定义覆盖参数:
#In one script that should stand-alone and include arg1:
parser = argparse.ArgumentParser(conflict_handler='resolve')
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
#In another script with similar options
parser.add_argument('--arg1', help='New number 1')
但这仍然包括 parse_args
的帮助消息和结果中的 arg1 是否有类似的东西
#Wishful thinking
#In another script with similar options, that shouldn't include arg1
parser.remove_argument('--arg1')
或者另一种相当简单的方法来实现这一点?
另外:如果参数是位置参数,方法会有所不同吗?
注意:按照建议 here 解析后删除 arg1
的问题是该参数仍然显示在帮助中
Is it possible to remove or disable an argument in argparse, such that
it does not show in the help?
添加参数时将help
设置为argparse.SUPPRESS
,如下所示:
parser.add_argument('--arg1', help=argparse.SUPPRESS)
这将阻止参数出现在默认帮助输出中。
尽管我在下面提到了错误问题,但您对 resolve
的使用表明了一种可能的方法。这不适合新手或需要坚持 public API.
的人
parser
有一个 Action(参数)对象列表(由 add_argument
创建)。
使用您的第二个解析器定义,它的 _actions
列表是:
In [22]: parser._actions
Out[22]:
[_HelpAction(option_strings=['-h', '--help'], dest='help'...),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,
const=None, default=None, type=None, choices=None,
help='A second one', metavar=None),
_StoreAction(option_strings=['--arg1'], dest='arg1', nargs=None,
const=None, default=None, type=None, choices=None,
help='New number 1', metavar=None)]
当您添加与 resolve
相冲突的操作时,它会删除存在冲突的现有操作。详情请看_handle_conflict_resolve
方法。但是我可以欺骗它删除一个动作而不添加一个新动作。
In [23]: parser._handle_conflict_resolve(None, [('--arg1',parser._actions[2])])
查看 _actions
并帮助验证 --arg1
是否已消失。
In [24]: parser._actions
Out[24]:
[_HelpAction(option_strings=['-h', '--help'], dest='help',....),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,...)]
In [25]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2]
optional arguments:
-h, --help show this help message and exit
--arg2 ARG2 A second one
resolve
仅处理 optionals
,其中标志字符串可能会发生冲突。它首先删除冲突的标志,只有在没有标志保留时才删除冲突的操作。所以当你有空头和多头选项时要格外小心。
这并没有解决位置问题。他们没有标志,他们可以共享 dest
参数。 (尽管只有一个会出现在结果中,除非他们正在附加操作)。
In [27]: foo1 = parser.add_argument('foo',help='foo 1 positional')
In [28]: foo2 = parser.add_argument('foo',help='foo 2 positional')
In [29]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo foo
positional arguments:
foo foo 1 positional
foo foo 2 positional
...
再玩一会儿,看来我可以删除其中一个新位置:
In [33]: parser._actions[-1]
Out[33]: _StoreAction(option_strings=[], dest='foo',... help='foo 2 positional', metavar=None)
In [35]: foo2=parser._actions[-1]
In [36]: foo2.container._remove_action(foo2)
In [39]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo
positional arguments:
foo foo 1 positional
....
如果我选择 _actions[-2]
,我会删除第一个 foo
。如果我将 add_argument
returns 的值分配给变量,例如foo1
,我可以使用它而不是在 parser._actions
列表中查找值。 运行 交互式 shell 中的示例解析器(我使用 IPython)并查看这些对象可能会有所帮助。
同样,这似乎适用于一个简单的示例,但如果用于更复杂的东西(或用于生产),则需要仔细测试。
几年前在 Python bugs/issues 上提出了这个话题:
http://bugs.python.org/issue19462 Add remove_argument() method to argparse.ArgumentParser
我讨论了完全删除的困难,并提出了一些替代方案。 argparse.SUPPRESS
可用于隐藏帮助。 optionals
如果不需要,可以忽略。 positionals
比较棘手,尽管我建议调整它们的属性(nargs
和 default
)。但是已经有一段时间了,所以我需要回顾一下这些帖子。
=============================
我很好奇 @2rs2ts
问题(见评论)。
我制作了一个解析器,然后将其用作另一个解析器的父级(无需使用子解析器机制)。然后我从一个解析器中删除了一个参数,并查看了另一个解析器中的变化。
用一个参数创建一个父解析器:
In [59]: p=argparse.ArgumentParser()
In [60]: p.add_argument('--foo')
Out[60]: _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
再做一个 parents
:
In [61]: p1=argparse.ArgumentParser(parents=[p],add_help=False)
In [62]: p1._actions
Out[62]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
请注意,两个解析器的第二个操作相同(相同的 ID)。 parents
只是复制了对原--foo
动作的引用,并没有进行复制。
In [63]: id(p._actions[1])
Out[63]: 3000108652
In [64]: id(p1._actions[1])
Out[64]: 3000108652
现在从一个解析器中删除“--foo”,使用我之前制定的技巧:
In [65]: p1._handle_conflict_resolve(None,[('--foo',p1._actions[1])])
In [66]: p1._actions
Out[66]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)]
'--foo' 已从 p1
列表中消失,但仍存在于 p
列表中。但是 option_strings
现在是空的。
In [67]: p._actions
Out[67]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
resolve
代码从 --foo
操作中删除了冲突的 option_strings
,然后将其从 p1._actions
列表中删除。但是更改 p1
引用的 option_strings
也更改了 p
引用。
argparse
使用几种方法来区分 positionals
和 optionals
,但在解析中最常用的方法是查看 option_strings
属性是否是空与否。通过清空这个属性,resolve
有效地将 optional
变成了 positional
.
糟糕,我的记忆力不对。:) 一年前我回答了一个类似的问题,涉及 parents
和 resolve
argparse conflict resolver for options in subcommands turns keyword argument into positional argument
删除 argparse 选项的函数:
def remove_options(parser, options):
for option in options:
for action in parser._actions:
if vars(action)['option_strings'][0] == option:
parser._handle_conflict_resolve(None,[(option,action)])
break
虽然 hpaulj 的回答很好,但就我而言 parser._remove_action(action)
并未从帮助中删除位置参数。它还需要从 _action_group
:
中删除
def remove_argument(parser, arg):
for action in parser._actions:
opts = action.option_strings
if (opts and opts[0] == arg) or action.dest == arg:
parser._remove_action(action)
break
for action in parser._action_groups:
for group_action in action._group_actions:
if group_action.dest == arg:
action._group_actions.remove(group_action)
return
要删除 --bar
,请调用:
remove_option(parser, "bar")
是否可以删除或禁用 argparse 中的参数,使其不显示在帮助中?怎么样?
添加新参数很容易:
parser = argparse.ArgumentParser()
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
而且我知道您可以通过指定 "resolve" 冲突处理程序来使用新定义覆盖参数:
#In one script that should stand-alone and include arg1:
parser = argparse.ArgumentParser(conflict_handler='resolve')
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
#In another script with similar options
parser.add_argument('--arg1', help='New number 1')
但这仍然包括 parse_args
的帮助消息和结果中的 arg1 是否有类似的东西
#Wishful thinking
#In another script with similar options, that shouldn't include arg1
parser.remove_argument('--arg1')
或者另一种相当简单的方法来实现这一点?
另外:如果参数是位置参数,方法会有所不同吗?
注意:按照建议 here 解析后删除 arg1
的问题是该参数仍然显示在帮助中
Is it possible to remove or disable an argument in argparse, such that it does not show in the help?
添加参数时将help
设置为argparse.SUPPRESS
,如下所示:
parser.add_argument('--arg1', help=argparse.SUPPRESS)
这将阻止参数出现在默认帮助输出中。
尽管我在下面提到了错误问题,但您对 resolve
的使用表明了一种可能的方法。这不适合新手或需要坚持 public API.
parser
有一个 Action(参数)对象列表(由 add_argument
创建)。
使用您的第二个解析器定义,它的 _actions
列表是:
In [22]: parser._actions
Out[22]:
[_HelpAction(option_strings=['-h', '--help'], dest='help'...),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,
const=None, default=None, type=None, choices=None,
help='A second one', metavar=None),
_StoreAction(option_strings=['--arg1'], dest='arg1', nargs=None,
const=None, default=None, type=None, choices=None,
help='New number 1', metavar=None)]
当您添加与 resolve
相冲突的操作时,它会删除存在冲突的现有操作。详情请看_handle_conflict_resolve
方法。但是我可以欺骗它删除一个动作而不添加一个新动作。
In [23]: parser._handle_conflict_resolve(None, [('--arg1',parser._actions[2])])
查看 _actions
并帮助验证 --arg1
是否已消失。
In [24]: parser._actions
Out[24]:
[_HelpAction(option_strings=['-h', '--help'], dest='help',....),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,...)]
In [25]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2]
optional arguments:
-h, --help show this help message and exit
--arg2 ARG2 A second one
resolve
仅处理 optionals
,其中标志字符串可能会发生冲突。它首先删除冲突的标志,只有在没有标志保留时才删除冲突的操作。所以当你有空头和多头选项时要格外小心。
这并没有解决位置问题。他们没有标志,他们可以共享 dest
参数。 (尽管只有一个会出现在结果中,除非他们正在附加操作)。
In [27]: foo1 = parser.add_argument('foo',help='foo 1 positional')
In [28]: foo2 = parser.add_argument('foo',help='foo 2 positional')
In [29]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo foo
positional arguments:
foo foo 1 positional
foo foo 2 positional
...
再玩一会儿,看来我可以删除其中一个新位置:
In [33]: parser._actions[-1]
Out[33]: _StoreAction(option_strings=[], dest='foo',... help='foo 2 positional', metavar=None)
In [35]: foo2=parser._actions[-1]
In [36]: foo2.container._remove_action(foo2)
In [39]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo
positional arguments:
foo foo 1 positional
....
如果我选择 _actions[-2]
,我会删除第一个 foo
。如果我将 add_argument
returns 的值分配给变量,例如foo1
,我可以使用它而不是在 parser._actions
列表中查找值。 运行 交互式 shell 中的示例解析器(我使用 IPython)并查看这些对象可能会有所帮助。
同样,这似乎适用于一个简单的示例,但如果用于更复杂的东西(或用于生产),则需要仔细测试。
几年前在 Python bugs/issues 上提出了这个话题:
http://bugs.python.org/issue19462 Add remove_argument() method to argparse.ArgumentParser
我讨论了完全删除的困难,并提出了一些替代方案。 argparse.SUPPRESS
可用于隐藏帮助。 optionals
如果不需要,可以忽略。 positionals
比较棘手,尽管我建议调整它们的属性(nargs
和 default
)。但是已经有一段时间了,所以我需要回顾一下这些帖子。
=============================
我很好奇 @2rs2ts
问题(见评论)。
我制作了一个解析器,然后将其用作另一个解析器的父级(无需使用子解析器机制)。然后我从一个解析器中删除了一个参数,并查看了另一个解析器中的变化。
用一个参数创建一个父解析器:
In [59]: p=argparse.ArgumentParser()
In [60]: p.add_argument('--foo')
Out[60]: _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
再做一个 parents
:
In [61]: p1=argparse.ArgumentParser(parents=[p],add_help=False)
In [62]: p1._actions
Out[62]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
请注意,两个解析器的第二个操作相同(相同的 ID)。 parents
只是复制了对原--foo
动作的引用,并没有进行复制。
In [63]: id(p._actions[1])
Out[63]: 3000108652
In [64]: id(p1._actions[1])
Out[64]: 3000108652
现在从一个解析器中删除“--foo”,使用我之前制定的技巧:
In [65]: p1._handle_conflict_resolve(None,[('--foo',p1._actions[1])])
In [66]: p1._actions
Out[66]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)]
'--foo' 已从 p1
列表中消失,但仍存在于 p
列表中。但是 option_strings
现在是空的。
In [67]: p._actions
Out[67]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
resolve
代码从 --foo
操作中删除了冲突的 option_strings
,然后将其从 p1._actions
列表中删除。但是更改 p1
引用的 option_strings
也更改了 p
引用。
argparse
使用几种方法来区分 positionals
和 optionals
,但在解析中最常用的方法是查看 option_strings
属性是否是空与否。通过清空这个属性,resolve
有效地将 optional
变成了 positional
.
糟糕,我的记忆力不对。:) 一年前我回答了一个类似的问题,涉及 parents
和 resolve
argparse conflict resolver for options in subcommands turns keyword argument into positional argument
删除 argparse 选项的函数:
def remove_options(parser, options):
for option in options:
for action in parser._actions:
if vars(action)['option_strings'][0] == option:
parser._handle_conflict_resolve(None,[(option,action)])
break
虽然 hpaulj 的回答很好,但就我而言 parser._remove_action(action)
并未从帮助中删除位置参数。它还需要从 _action_group
:
def remove_argument(parser, arg):
for action in parser._actions:
opts = action.option_strings
if (opts and opts[0] == arg) or action.dest == arg:
parser._remove_action(action)
break
for action in parser._action_groups:
for group_action in action._group_actions:
if group_action.dest == arg:
action._group_actions.remove(group_action)
return
要删除 --bar
,请调用:
remove_option(parser, "bar")