我可能在这里找到了解决方案。诚然,这是一个肮脏的黑客,但它的工作原理。
注意:以下所有内容均适用于 Python 3.3.2。
根据此处的答案,parse_args
检查需要哪些操作,如果缺少任何操作,则会引发错误。我建议覆盖这种行为。
通过子类化ArgumentParser
,我们可以定义一个新方法(此处ArgumentParser.error
为原始方法),该方法将检查是否由于缺少某些参数而引发错误并采取必要的措施。代码如下:
import argparse
import sys
from gettext import gettext as _
class ArgumentParser(argparse.ArgumentParser):
skip_list = []
def error(self, message):
# Let's see if we are missing arguments
if message.startswith('the following arguments are required:'):
missingArgs = message.split('required: ')[1].split(', ')
newArgs = [] # Creating a list of whatever we should not skip but is missing
for arg in missingArgs:
if arg not in self.skip_list:
newArgs.append(arg)
else:
self.skip_list.remove(arg) # No need for it anymore
if len(newArgs) == 0:
return # WARNING! UNTESTED! MAY LEAD TO SPACETIME MELTDOWN!
else: # Some required stuff is still missing, so we show a corrected error message
message = _('the following arguments are required: %s') % ', '.join(newArgs)
self.print_usage(sys.stderr) # Original method behavior
args = {'prog': self.prog, 'message': message}
self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
新方法首先检查错误是否是因为命令行中缺少参数(请参阅此处了解生成错误的代码)。如果是这样,该方法从错误消息中获取参数的名称并将它们放入一个列表 ( missingArgs
) 中。
然后,我们遍历这个列表并检查哪些参数应该被跳过,哪些仍然是必需的。为了确定要跳过哪些参数,我们将它们与skip_list
. 它是我们ArgumentParser
子类中的一个字段,它应该包含要跳过的参数的名称,即使解析器需要它们。请注意,碰巧在其中的参数在skip_list
找到时会从其中删除。
如果命令行中仍然缺少必需的参数,则该方法会引发更正的错误消息。但是,如果应跳过所有缺少的参数,则该方法将返回。
警告!的原始定义ArgumentParser.error
表明,如果它在子类中被覆盖,则不应返回,而是退出或引发异常。因此,此处显示的内容可能不安全,可能会导致您的程序崩溃、您的计算机着火或更糟——它可能会蒸发掉您所有的茶。但是,在这种特殊情况下(缺少必需的参数),从方法返回似乎是安全的。但它可能不是。你被警告了。
为了填充skip_list
,我们可以使用如下代码:
class SpecialHelp(argparse._HelpAction):
def __call__(self, parser, namespace, values, option_string=None):
parser.print_help()
print()
for action in parser._actions:
if action != self and action.required:
parser.skip_list.append(argparse._get_action_name(action))
这个特定的类模仿了内置的help
动作,但它没有退出,而是将所有剩余的必需参数插入到skip_list
.
希望我的回答对您有所帮助,祝您好运。