python argparse在使用特定选项时忽略其他选项 [英] python argparse ignore other options when a specific option is used
问题描述
我正在编写一个 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屋!