Python OptPass默认值与函数默认值

Python OptPass默认值与函数默认值,python,dry,optparse,Python,Dry,Optparse,我正在编写一个python脚本,我希望能够从命令行调用该脚本,并将其作为库函数导入。 理想情况下,命令行选项和函数应使用相同的默认值集。 允许我在这两个地方重用一组默认值的最佳方法是什么 以下是当前代码,默认值重复 from optparse import OptionParser def do_stuff(opt1="a", opt2="b", opt3="c"): print opt1, opt2, opt3 if __name__ == "__main__": pars

我正在编写一个python脚本,我希望能够从命令行调用该脚本,并将其作为库函数导入。 理想情况下,命令行选项和函数应使用相同的默认值集。 允许我在这两个地方重用一组默认值的最佳方法是什么

以下是当前代码,默认值重复

from optparse import OptionParser

def do_stuff(opt1="a", opt2="b", opt3="c"):
    print opt1, opt2, opt3

if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option("--opt1", default="a")
    parser.add_option("--opt2", default="b")
    parser.add_option("--opt3", default="c")
    #parser.set_defaults(opt1="a")

    options, args = parser.parse_args()

    do_stuff(*args, **vars(options))

这是一个解决方案-如果您只需要关键字参数,那么它很简单-只需使用locals.update。以下句柄包括位置参数和关键字参数(关键字参数替代位置参数)

输出:

a b c 
a b c 
d e f 
d e b 
c a b 

我会通过内省感兴趣的函数来适当地设置选项和默认值来处理它。例如:

import inspect
from optparse import OptionParser
import sys

def do_stuff(opt0, opt1="a", opt2="b", opt3="c"):
    print opt0, opt1, opt2, opt3

if __name__ == "__main__":
    parser = OptionParser()
    args, varargs, varkw, defaults = inspect.getargspec(do_stuff)
    if varargs or varkw:
      sys.exit("Sorry, can't make opts from a function with *a and/or **k!")
    lend = len(defaults)
    nodef = args[:-lend]
    for a in nodef:
      parser.add_option("--%s" % a)
    for a, d in zip(args[-lend:], defaults):
      parser.add_option("--%s" % a, default=d)

    options, args = parser.parse_args()
    d = vars(options)
    for n, v in zip(nodef, args):
      d[n] = v

    do_stuff(**d)

Alex的inspect解决方案非常强大

对于轻量级程序,您也可以简单地使用:

def do_stuff(opt1="a", opt2="b", opt3="c"):
    print opt1, opt2, opt3

if __name__ == "__main__":
    from optparse import OptionParser
    opts = do_stuff.func_defaults
    parser = OptionParser()    
    parser.add_option("--opt1", default=opts[0], help="Option 1 (%default)")
    parser.add_option("--opt2", default=opts[1], help="Option 2 (%default)")
    parser.add_option("--opt3", default=opts[2], help="Option 3 (%default)")

    options, args = parser.parse_args()

    do_stuff(*args, **vars(options))
def do_stuff(opt1="a", opt2="b", opt3="c"):
    print opt1, opt2, opt3

if __name__ == "__main__":
    from optparse import OptionParser
    opts = do_stuff.func_defaults
    parser = OptionParser()    
    parser.add_option("--opt1", default=opts[0], help="Option 1 (%default)")
    parser.add_option("--opt2", default=opts[1], help="Option 2 (%default)")
    parser.add_option("--opt3", default=opts[2], help="Option 3 (%default)")

    options, args = parser.parse_args()

    do_stuff(*args, **vars(options))