python argparse在使用特定选项时忽略其他选项 [英] python argparse ignore other options when a specific option is used

查看:23
本文介绍了python argparse在使用特定选项时忽略其他选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a python program that I want to have a command line interface that behaves in a particular way

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

The command line interface should accept the following invocations:

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

(它将生成一个 svg,其中包含以指定或默认字体编写的 foo 字样)

(it will generate an svg with the word foo written in the specified or default font)

现在我希望也能够让这个命令接受以下调用...

Now I want to be able to also have this command accept the following invocation...

my_prog --list-fonts

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

which will list all of the valid options to --font as determined by the fonts available on the system.

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

I am using argparse, and I have something like this:

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 选项表现得像我希望的那样,因为仍然需要两个位置参数.

however this does not make the --list-fonts option behave as I would like as the two positional arguments are still required.

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

I have also tried using subparsers, but these still need a workaround to prevent the other options being required every time.

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

How do I get the desired behaviour with argparse.

推荐答案

argparse 允许您根据 add_argument<的 action 关键字参数定义遇到参数时要采取的任意操作/code>(查看文档)

argparse allows you to define arbitrary actions to take when encountering an argument, based on the action keyword argument to add_argument (see the docs)

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

You can define an action to list your fonts and then abort argument parsing, which will avoid checking for the other required arguments.

这可能是这样的:

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

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

Then you can add it to your argument like so:

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

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

Note nargs=0 has been added so that this argument doesn't require a value (the code in the question achieved this with action='store_true')

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

This solution has a side-effect of enabling the invocations like the following to also list the fonts and exits without running the main program:

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

这可能不是问题,因为它不是一个典型的用例,特别是如果帮助文本解释了这种行为.

This is likely not a problem as it's not a typical use case, especially if the help text explains this behaviour.

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

If defining a new class for each such option feels too heavyweight, or perhaps you have more than one option that has this behaviour, then you could consider having a function that implements the desired action for each argument and then have a kind of factory function that returns a class that wraps the function. A complete example of this is shown below.

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()

这篇关于python argparse在使用特定选项时忽略其他选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆