2009-10-02 15 views
6

Piszę skrypt Pythona, który chciałbym móc wywoływać zarówno z linii poleceń, jak i importować jako funkcję biblioteki. Idealnie opcje wiersza poleceń i funkcja powinny używać tego samego zestawu wartości domyślnych. Jaki jest najlepszy sposób, aby umożliwić ponowne użycie pojedynczego zestawu wartości domyślnych w obu miejscach?Python optparse domyślnie kontra domyślne funkcje

Oto aktualny kod z podwójnymi wartościami domyślnymi.

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

Odpowiedz

3

bym sobie to poprzez introspekcję funkcję zainteresowania ustawić domyślne opcje i odpowiednio. Na przykład:

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

Oto rozwiązanie - to banalne, jeśli potrzebujesz tylko argumentów słów kluczowych - po prostu użyj locals.update. Kolejno obsługuje zarówno argumenty pozycyjne, jak i słowa kluczowe (słowa kluczowe przejmują pozycje).

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

wyjściowa:

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

Sprawdzone rozwiązanie autorstwa Alex jest bardzo wydajne!

lekkich programów, można też po prostu użyć tego:

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