如何根据用户输入修改optparse的nargs参数?

0 投票
1 回答
1250 浏览
提问于 2025-04-18 10:13

这个问题是之前一个问题的延续,链接在这里:如何访问optparse-add_action的nargs?

之前的问题已经得到了回答,解决了当时的需求。

简要说明:

假设我使用下面的add_option工具:

parser.add_option('-c','--categories', dest='Categories', nargs=4 )

有没有办法通过用户输入来修改add_option()中的nargs呢?可以使用raw_input吗?

编辑: 我会清楚地说明我“之前问题的需求”和“这个问题的需求”之间的区别。

第一个问题的情况:

如果用户没有提供任何输入,我的脚本会询问用户输入,也就是说,用户只是运行了:

#./commandparser.py

第二个问题的需求是:

当我运行我的脚本 ./commandparser.py -c abc bac cad 时,它会抛出错误:commandparser.py: error: -c option requires 4 arguments并退出脚本。

我希望的是,不要抛出错误并退出脚本,而是有一种机制可以让它询问用户输入剩下的参数,也就是第4个参数,而不退出脚本。

1 个回答

0

你是不是想要接受一个可变数量的值作为这个选项?也就是说,使用 'rawinput' 来设置 nargs,然后用它来解析命令行?

optparse 的文档里有一个例子,展示了如何使用自定义回调来处理可变数量的值:

https://docs.python.org/2/library/optparse.html#callback-example-6-variable-arguments

argparse 则允许使用可变数量的值,nargs 可以设置为 '?'(0或1个),'+'(1个或多个),'*'(0个或多个)。


因为我对 argparse 更熟悉,所以我会简单描述一个交互式脚本来满足你的新需求:

import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-c', '--categories', nargs='+', help='4 categories', default=[])
args = parser.parse_args()
print(args)
categories = args.categories
while len(categories)<4:
    print(parser.format_usage())
    x = raw_input('enter %s categories: '%(4-len(categories))).split()
    categories.extend(x)
print('categories', categories)

如果 'categories' 是唯一的参数,你可以用 categories = sys.argv[1:] 来替代所有的 argparse(或者 optparse)的内容,或者如果你还希望有 '-c' 这个标志的话,可以用 [2:]


或者使用 optparse(根据文档中关于可变长度回调的例子进行调整):

def vararg_callback(option, opt_str, value, parser):
     value = []
     for arg in parser.rargs:
         # stop on --foo like options
         if arg[:2] == "--" and len(arg) > 2:
             break
         # stop on -a (ignore the floats issue)
         if arg[:1] == "-" and len(arg) > 1:
             break
         value.append(arg)
     del parser.rargs[:len(value)]
     setattr(parser.values, option.dest, value)

def use_opt():
    import optparse
    parser = optparse.OptionParser()
    parser.add_option('-c','--categories', dest='categories', action="callback", callback=vararg_callback)
    (options, args) = parser.parse_args()
    print options, args
    return options, args, parser

args, rest, parser = use_opt()

撰写回答