2009-10-02 41 views
6

Tôi đang viết một tập lệnh python mà tôi muốn có thể gọi cả từ dòng lệnh và nhập dưới dạng hàm thư viện. Lý tưởng nhất là các tùy chọn dòng lệnh và hàm nên sử dụng cùng một bộ giá trị mặc định. Cách tốt nhất để cho phép tôi sử dụng lại một tập hợp mặc định duy nhất ở cả hai nơi là gì?Mặc định mặc định của Python so với mặc định của hàm

Đây là mã hiện tại có mặc định trùng lặp.

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

Trả lời

3

tôi muốn xử lý nó bằng cách introspecting chức năng quan tâm để đặt tùy chọn và mặc định một cách thích hợp. Ví dụ:

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

Đây là giải pháp - nó tầm thường nếu bạn chỉ cần đối số từ khóa - chỉ cần sử dụng locals.update. Sau xử lý cả hai, arg từ vị trí và khóa (từ khóa arg ghi đè vị trí).

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

Output:

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

Giải pháp kiểm tra của Alex rất mạnh!

Đối với chương trình nhẹ, bạn cũng có thể chỉ cần sử dụng này:

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)) 
Các vấn đề liên quan