我正在努力将Python中一个具有默认参数的API函数与一个使用optparse包装它的命令行脚本干净地结合起来。让我们假设API函数如下:
def api(foo, bar, opt1 = 2, opt2 = 3):
pass
命令行工具的OptionParser看起来如下
parser = OptionParser(usage=usage, description=desc, version=version)
parser.add_option("-a", "--opt1", type="int", action="store", help="opt1")
parser.add_option("-b", "--opt2", type="int", action="store", help="opt2")
parser.add_option("-v", "--verbose", action="store", help="verbosity")
(opt, args) = parser.parse_args()
在这一点上,我希望CLI调用api((,为foo和bar提供一个值,并在指定了opt1/opt2选项的情况下传播这些选项,否则会省略这些参数,从而使用默认值2和3。最好的方法是什么?请记住,命令行选项"verbose"不适用于api((。
我希望在API而不是OptionParser中使用默认值,因为有时API是以库的方式调用的,并且应该应用与CLI情况相同的默认值。最重要的是,我不希望在没有指定opt1或opt2的情况下传播opts中的None值。
我需要使用OptionParser,但argparse的答案也很有趣。
谢谢你抽出时间。
编辑:
以下是我使用检查模块得出的最好的结果:
kws = {}
param_names = inspect.getargspec(api)[0]
kws.update((k, v) for k, v in opt.__dict__.items() if v is not None and k in param_names)
api(foo, bar, **kws)
parser = OptionParser(usage=usage, description=desc,
version=version)
parser.add_option("-a", "--opt1", type="int", action="store",
help="opt1")
parser.add_option("-b", "--opt2", type="int", action="store",
help="opt2")
parser.add_option("-v", "--verbose", action="store",
help="verbosity")
(opt, args) = parser.parse_args()
optional_arguments = dict((k, v) for k, v in vars(opt).items()
if v and k in ['op1', 'op2'])
api('the foo', 'the bar', **optional_arguments)
讨论
vars(opt)
返回字典,例如{'opt1': None, 'opt2': None, 'verbose': None}
- 整个
dict( ... )
表达式过滤掉那些值不是None
的选项,并返回一个dictionary对象。我也可以为此使用filter()
- 此字典对象可以输入
api()
更新
我在创建optional_arguments
时添加了and k in ['op1', 'op2']
,以防止其他参数进入参数列表。