2009-10-02 102 views
6

我正在寫一個python腳本,我希望能夠從命令行調用並導入爲庫函數。 理想情況下,命令行選項和函數應使用相同的一組默認值。 允許我在這兩個地方重複使用一組默認設置的最佳方法是什麼?Python optparse默認值vs函數默認值

下面是當前代碼的重複默認值。

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)) 

回答

3

我會通過自檢感興趣的功能,適當地設置選項和缺省值處理。例如:

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) 
2

以下是解決方案 - 如果您只需要關鍵字參數,這很簡單 - 只需使用locals.update即可。以下句柄同時處理位置和關鍵詞args(關鍵詞args覆蓋位置)。

from optparse import OptionParser 

ARGS = {'opt1': 'a', 
     'opt2': 'b', 
     'opt3': 'c'} 

def do_stuff(*args, **kwargs): 
    locals = ARGS 

    keys = ARGS.keys() 
    keys.sort() 

    if args: 
     for key,arg in zip(keys,args): 
      locals.update({key: arg}) 
    if kwargs: 
     locals.update(kwargs) 

    print locals['opt1'], locals['opt2'], locals['opt3'] 

if __name__ == "__main__": 
    parser = OptionParser() 
    for key,default in ARGS.items(): 
     parser.add_option('--%s' % key, default='%s' % default) 

    options, args = parser.parse_args() 

    do_stuff(*args, **vars(options)) 
    do_stuff() 
    do_stuff('d','e','f') 
    do_stuff('d','e','f', opt3='b') 
    do_stuff(opt1='c', opt2='a', opt3='b') 

輸出:

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

亞歷克斯的檢測解決方案非常強大!

對於輕量級的程序,你也可以簡單地使用:

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))