【问题标题】:Combining an API function with argument defaults with an OptionParser将 API 函数与参数默认值与 OptionParser 相结合
【发布时间】:2013-04-01 10:05:17
【问题描述】:

我正在努力将 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)

【问题讨论】:

    标签: python argparse optparse


    【解决方案1】:
    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()

    更新

    我在创建optional_arguments 时添加了and k in ['op1', 'op2'],以防止其他参数进入参数列表。

    【讨论】:

    • 谢谢,吴海。看起来我们几乎在同一页上。我在您的方法中看到的唯一问题是,我认为它会将“详细”关键字参数传递给 api(),这将导致运行时错误。我在上面的尝试使用了检查来解决这个问题。我只是想知道是否有更好或内置的方法来做到这一点。根据您的回答,也许这是最好的 =)
    • 查看我的更新。我添加了代码以防止 opt1opt1 以外的参数进入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 2019-12-26
    • 2016-12-13
    相关资源
    最近更新 更多