【问题标题】:python argparse ignore other options when a specific option is usedpython argparse 在使用特定选项时忽略其他选项
【发布时间】:2019-04-25 08:17:26
【问题描述】:

我正在编写一个 python 程序,我希望有一个以特定方式运行的命令行界面

命令行界面应该接受以下调用:

my_prog test.svg foo
my_prog --font=Sans test.svg foo

(它会生成一个带有foo字样的svg,以指定或默认字体书写)

现在我希望这个命令也能接受下面的调用...

my_prog --list-fonts

这将列出--font 的所有有效选项,由系统上可用的字体确定。

我正在使用argparse,我有这样的东西:

parser = argparse.ArgumentParser()

parser.add_argument('output_file')
parser.add_argument('text')
parser.add_argument('--font', help='list options with --list-fonts')
parser.add_argument('--list-fonts', action='store_true')

args = parser.parse_args()

但是,这不会使 --list-fonts 选项的行为符合我的意愿,因为仍然需要两个位置参数。

我也尝试过使用子解析器,但这些仍然需要解决方法以防止每次都需要其他选项。

如何使用 argparse 获得所需的行为。

【问题讨论】:

  • 如果你有一个nargs='*' 的位置,它应该接受所有的替代方案。解析后,您可以检查位置是否具有正确数量的字符串,并在必要时引发错误(或忽略不需要的值)。否则我认为你必须走自定义的Action 路线。

标签: python-3.x argparse


【解决方案1】:

argparse 允许您根据 add_argument (see the docs) 的 action 关键字参数定义遇到参数时要采取的任意操作

您可以定义一个操作来列出您的字体,然后中止参数解析,这将避免检查其他必需的参数。

这可能看起来像这样:

class ListFonts(argparse.Action):
    def __call__(self, parser, namespace, values, option_string):
        print("list of fonts here")
        parser.exit() # exits the program with no more arg parsing and checking

然后你可以像这样将它添加到你的论点中:

parser.add_argument('--list-fonts', nargs=0, action=ListFonts)

注意 nargs=0 已添加,因此此参数不需要值(问题中的代码使用 action='store_true' 实现了这一点)

此解决方案有一个副作用,即启用如下调用以在不运行主程序的情况下也列出字体和退出:

my_prog --font Sans test.svg text --list-fonts

这可能不是问题,因为它不是典型的用例,尤其是在帮助文本解释了这种行为的情况下。

如果为每个此类选项定义一个新类感觉过于繁重,或者您可能有多个具有此行为的选项,那么您可以考虑使用一个函数来为每个参数实现所需的操作,然后使用一种工厂函数,它返回一个包装函数的类。一个完整的例子如下所示。

def list_fonts():
    print("list of fonts here")

def override(func):
    """ returns an argparse action that stops parsing and calls a function
    whenever a particular argument is encountered. The program is then exited """
    class OverrideAction(argparse.Action):
        def __call__(self, parser, namespace, values, option_string):
            func()
            parser.exit()
    return OverrideAction

parser = argparse.ArgumentParser()

parser.add_argument('output_file')
parser.add_argument('text')
parser.add_argument('--font', help='list options with --list-fonts')
parser.add_argument('--list-fonts', nargs=0, action=override(list_fonts),
    help='list the font options then stop, don\'t generate output')
args = parser.parse_args()

【讨论】:

  • 谢谢!我在脚本中添加了一个测试模式选项 (--test),并希望在指定 --test 时忽略其他通常需要的参数。为此,我使用了您的 sn-p,但扩展了 argparse._StoreTrueAction 而不是 argparse.Action(对于 action='store_true' 类似的行为)。然后我添加了一个自定义异常并在调用 parse_args() 期间捕获了它。
猜你喜欢
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 2012-11-15
  • 2021-12-22
  • 2016-08-11
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多