我正在努力干净地将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)
答案 0 :(得分:0)
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
的选项并返回一个字典对象。我也可以使用filter()
来实现此目的。api()
我在and k in ['op1', 'op2']
的创建中添加了optional_arguments
,以防止其他参数进入参数列表。