5

私は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
値:なし

選択:
{'テスト':'テスト'}
args:
['foo']

なぜ'foo'渡されずstore_test()、代わりに追加の引数として解釈されるのですか?何か問題がありop.parse_args(['-t', 'foo'])ますか?

↓</h2>

http://codepad.org/vq3cvE13

編集:

ドキュメントの例を次に示します。

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

1 に答える 1

6

You're missing a "type" or "nargs" option attribute:

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

This option will cause it to consume the next argument.

Reference: http://docs.python.org/library/optparse.html#optparse-option-callbacks

type
has its usual meaning: as with the "store" or "append" actions, it instructs optparse to consume one argument and convert it to type. Rather than storing the converted value(s) anywhere, though, optparse passes it to your callback function.

nargs
also has its usual meaning: if it is supplied and > 1, optparse will consume nargs arguments, each of which must be convertible to type. It then passes a tuple of converted values to your callback.

This seems to be the relevant code from 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)
于 2011-07-05T14:20:29.317 に答える