(标题应为OptionParser: show extra help
,但标题中不允许使用help
字样
我有OptionParser
:
parser = OptionParser(
usage='usage: %s [options]' % (args[0]),
version='%s Version %s' % (args[0], version))
parser.add_option('-a', '--action', choices=['menu'] , help='Allowed actions are: menu, and any menu action', default='menu')
parser.add_option('-1', '--file1', type='string', help='First file')
parser.add_option('-2', '--file2', type='string', help='Second file')
parser.add_option('--debug', action='store_true', help='run in debug mode')
使用--help
致电给我:
Usage: /home/gonvaled/projects/bin/process_json.py [options]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-a ACTION, --action=ACTION
Allowed actions are: menu, and any menu action
-1 FILE1, --file1=FILE1
First file
-2 FILE2, --file2=FILE2
Second file
--debug run in debug mode
这很好,但缺少动作。问题是某些操作是在Menu
对象(我的实现)中定义的,只能通过执行以下操作来显示:
menu.showCommands()
也就是说,这些操作没有为OptionParser
定义,但仍然可以通过命令行访问,因为menu
以外的任何操作都将透明地传递给Menu
对象被处理。因此,OptionParser
提供的帮助并不了解这些行为。
如何告诉OptionParser
对象在显示帮助文本时,必须添加一些外部信息?追加到最后就足够了。我看了docs,但似乎没有这样的选择。
实际上运行我的程序表明不仅缺少帮助。更糟糕的是:optparse
抱怨未知行为:
gonvaled@pegasus ~ » process_json.py -a prettyfy-from-obj
Usage: /home/gonvaled/projects/bin/process_json.py [options]
process_json.py: error: option -a: invalid choice: 'prettyfy-from-obj' (choose from 'menu')
如何告诉optparse
接受action
的未指定值?
答案 0 :(得分:0)
您发送到choices
参数的列表必须是该选项允许的所有可能参数的详尽列表。如果列表为['menu']
,则唯一允许的值为menu
。这解释了你得到的错误。
注意:the optparse
module is deprecated,您应该使用argparse
不要使用choices
并在之后验证参数。
parser.add_option('-a', '--action', help='Allowed actions are: menu, and any menu action', default='menu')
#...
options, args = parser.parse_args()
if options.action not in menu.showCommands():
parser.error('Invalid action specified: %s' % options.action)
或者,如果您不能这样做,如果您使用调用menu.call(action, params)
的操作并引发UnavailableAction
例外:
parser.add_option('-a', '--action', help='Allowed actions are: menu, and any menu action', default='menu')
#...
options, args = parser.parse_args()
# do something as normal
try:
menu.call(options.action, params)
except UnavailableAction:
print "Incorrect option" # (1)
# crash appropriately
如果解析器对象可用,您可以更改(1)
以获取以下内容:
parser.error('Invalid action specified: %s' % options.action)
注意:这完全违背了使用choices
的目的,但如果您无法在解析CLI的函数/方法/模块的范围内进行验证,则可以适用选项。
此问题的任何其他解决方案取决于您是否能够内省menu
对象以获取可用操作列表。
假设menu.showCommands
只提供可用命令的字符串列表,我的第一个猜测是做类似的事情:
menu_choices = menu.showCommands().split()
menu_choices.append('menu')
parser.add_option('-a', '--action', choices=menu_choices , help='Allowed actions are: menu, and any menu action', default='menu')
如果无法获取该格式的操作列表,您可能需要“解析”menu.showCommands
的输出
您还可以将其实现为-a
选项的回调:
def menu_option(option, opt_str, value, parser):
if not value not in menu.showCommands().split():
raise OptionValueError('Invalid action for menu')
parser.add_option('-a', '--action', action='callback', callback=menu_option, help='Allowed actions are: menu, and any menu action', default='menu')
此选项更灵活一些。例如,如果您使用名为has_action(menu, string)
的函数来检查menu
对象是否有可用的string
操作,则可以执行以下操作:
def menu_option(option, opt_str, value, parser):
if not has_action(menu, value):
raise OptionValueError('Invalid action specified for menu: %s' % value)
可能有更复杂的解决方案。一些想法(可能或者 - 更可能 - 不起作用)是:
OptionParser
并创建您自己的所需内容(以便选择无效)menu
有自己的OptionParser
,请使用回调对其进行链式加载menu
有自己的子解析器,have argparse use it directly