Optparse callback не потребляющий аргумент - PullRequest
5 голосов
/ 05 июля 2011

Я пытаюсь узнать optparse немного лучше, но я изо всех сил пытаюсь понять, почему следующий код ведет себя так, как он. Я что-то делаю глупо?

import optparse

def store_test(option, opt_str, value, parser, args=None, kwargs=None):
    print 'opt_str:', opt_str
    print 'value:', value

op = optparse.OptionParser()
op.add_option('-t', '--test', action='callback', callback=store_test, default='test', 
    dest='test', help='test!')

(opts, args) = op.parse_args(['test.py', '-t', 'foo'])

print
print 'opts:'
print opts
print 'args:'
print args

Выход:

opt_str: -t
value: None

opts:
{'test': 'test'}
args:
['foo']

Почему 'foo' не передается store_test(), а интерпретируется как дополнительный аргумент? Что-то не так с op.parse_args(['-t', 'foo'])?

http://codepad.org/vq3cvE13

Edit:

Вот пример из документации:

def store_value(option, opt_str, value, parser):
    setattr(parser.values, option.dest, value)
[...]
parser.add_option("--foo",
                  action="callback", callback=store_value,
                  type="int", nargs=3, dest="foo")

1 Ответ

6 голосов
/ 05 июля 2011

Вам не хватает атрибута "type" или "nargs" :

op.add_option('-t', '--test', action='callback', callback=store_test, default='test',
    dest='test', help='test!', type='str')

Эта опция заставит его использовать следующий аргумент.

Ссылка: http://docs.python.org/library/optparse.html#optparse-option-callbacks

Тип
имеет свое обычное значение: как и при действиях "store" или "append", он дает команду optparse использовать один аргумент и преобразовать его в тип. Вместо того, чтобы хранить преобразованный хотя значения в любом месте, optparse передает их вашей функции обратного вызова.

nargs
также имеет свое обычное значение: если он задан и> 1, optparse будет потреблять nargs аргументы, каждый из которых должен быть преобразован в тип. Затем он передает кортеж преобразованных значения для вашего обратного вызова.

Это, кажется, соответствующий код из optparse.py:

def takes_value(self):
    return self.type is not None

def _process_short_opts(self, rargs, values):
    [...]
        if option.takes_value():
            # Any characters left in arg?  Pretend they're the
            # next arg, and stop consuming characters of arg.
            if i < len(arg):
                rargs.insert(0, arg[i:])
                stop = True

            nargs = option.nargs
            if len(rargs) < nargs:
                if nargs == 1:
                    self.error(_("%s option requires an argument") % opt)
                else:
                    self.error(_("%s option requires %d arguments")
                               % (opt, nargs))
            elif nargs == 1:
                value = rargs.pop(0)
            else:
                value = tuple(rargs[0:nargs])
                del rargs[0:nargs]

        else:                       # option doesn't take a value
            value = None

        option.process(opt, value, values, self)
...