When specifying help in argparse, I often use strings like %(default)s or %(const)s in the help= argument to display default arguments. The syntax is a bit weird, though: I assume it's left over from the days where python strings were formatted with %, but since python 2.6 the standard way to format strings has been using the format() function.

So are these libraries just using the 'old' replacement syntax, or does this come from somewhere else? It's been stated that the % replacement operator will disappear at some point, will these libraries change to the '{}'.format() syntax then?

有帮助吗?

解决方案

Yes, the argparse and ConfigParser libraries use the old-style % string formatting syntax internally. These libraries were developed before str.format() and format() were available, or in the case of argparse the library authors aimed at compatibility with earlier Python versions.

If the % formatting ever is removed, then those libraries will indeed have to move to using string formatting using {} placeholders.

However, for various reasons, the % old-style string formatting style is here to stay for the foreseeable future; it has been 'un-deprecated'; str.format() is to be preferred but % is kept around for backwards compatibility.

其他提示

The approved way of customizing the help formatting is to subclass HelpFormatter. A user can do this without waiting for a future Python release.

This formatter implements the {}.format in 2 places.

class NewHelpFormatter(argparse.HelpFormatter):
    # _format_usage - format usage, but only uses dict(prog=self._prog)
    def _format_text(self, text):
        # for description, epilog, version
        if '{prog}' in text:
            text = text.format(prog=self._prog) # change from %
        text_width = self._width - self._current_indent
        indent = ' ' * self._current_indent
        return self._fill_text(text, text_width, indent) + '\n\n'
    def _expand_help(self, action):
        params = dict(vars(action), prog=self._prog)
        for name in list(params):
            if params[name] is argparse.SUPPRESS:
                del params[name]
        for name in list(params):
            if hasattr(params[name], '__name__'):
                params[name] = params[name].__name__
        if params.get('choices') is not None:
            choices_str = ', '.join([str(c) for c in params['choices']])
            params['choices'] = choices_str
        return self._get_help_string(action).format(**params) # change from %

For example:

parser = argparse.ArgumentParser(prog='NewFormatter',
    formatter_class=NewHelpFormatter,
    description='{prog} description')
parser.add_argument('foo',nargs=3, default=[1,2,3],
    help='nargs:{nargs} prog:{prog!r} defaults:{default} last:{default[2]}')
parser.add_argument('--bar',choices=['yes','no'],
    help='choices: {choices!r}')
parser.print_help()

produces:

usage: NewFormatter [-h] [--bar {yes,no}] foo foo foo

NewFormatter description

positional arguments:
  foo             nargs:3 prog:'NewFormatter' defaults:[1, 2, 3] last:3

optional arguments:
  -h, --help      show this help message and exit
  --bar {yes,no}  choices: 'yes, no'
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top