Как избежать использования заглавных букв в модуле argparse Python?

Был задан вопрос, откуда они берутся, и принятым ответом была куча ссылок на руководства и исходный код. Объяснение поведения модуля argparse python: где Откуда взялись заполнители для заглавных букв?

Ничего из этого мне не помогло, я хочу либо избавиться от них, либо узнать их назначение.

Например, такая строка:

parser.add_argument('-c', '--chunksize', type=int, help='chunk size in bits')

производит такой мусор:

optional arguments:
  -h, --help            show this help message and exit
  -c CHUNKSIZE, --chunksize CHUNKSIZE
                        chunk size in bits

и если я попробую с пустой строкой метавара:

parser.add_argument('-c', '--chunksize', metavar='', type=int, help='chunk size in bits')

Я получаю пробел после запятой:

optional arguments:
  -h, --help            show this help message and exit
  -c , --chunksize      chunk size in bits

person bug    schedule 06.06.2013    source источник
comment
Я думал, что argparse.SUPPRESS может помочь, но, видимо, нет...   -  person mgilson    schedule 06.06.2013
comment
Каков ваш желаемый результат? -c chunksize, --chunksize chunksize вместо -c CHUNKSIZE, --chunkesize CHUNKSIZE? Тогда это сделает metavar = ('chunksize'). Никакой линии помощи вообще по этому аргументу? help=argparse.SUPPRESS   -  person Nisan.H    schedule 06.06.2013
comment
Что бы это ни стоило, я думаю, что поведение по умолчанию лучше — оно более явно указывает, какие параметры принимают аргумент (и сколько). Конечно, я не пишу программу, поэтому мой вклад здесь может не иметь значения (и это нормально) — я просто выражаю свои чувства по этому поводу.   -  person mgilson    schedule 06.06.2013
comment
@Nisan.H -- я думаю, что ОП ищет -c, --chunksize ______ chunksize in bits   -  person mgilson    schedule 06.06.2013
comment
Кроме того, взгляните на MetavarTypeHelpFormatter по адресу docs.python.org/dev. /library/argparse.html#formatter-class, и если это не сработает, вы можете взять исходный код и создать подкласс своего собственного средства форматирования, чтобы форматировать вещи так, как вы хотите.   -  person Nisan.H    schedule 06.06.2013
comment
Я только что заметил, что MetavarTypeHelpFormatter доступен только в версии 3.3 и выше. Я напишу ответ для пользовательского форматера.   -  person Nisan.H    schedule 06.06.2013


Ответы (3)


parser.add_argument('-c', '--chunksize', metavar='\b', type=int, help='chunk size in bits')

кажется работает

person Aravind    schedule 06.06.2013
comment
Аккуратный хак, лол. Я не могу поверить, что это правильный способ сделать это. - person bug; 07.06.2013
comment
ты сам это сказал; это хак, так что не может быть правильно, лол - person Aravind; 10.06.2013
comment
Это испортит отступ описания опции - person user1948847; 04.06.2014

Вы можете сделать свой класс форматирования для форматирования аргументов в зависимости от того, как вы хотите. Это не совсем прямолинейно, но вот тот, который дает следующий вывод (при условии, что @mgilson верен в предположении, что вы хотите отображать метавар только один раз для набора имен команд... В противном случае просто укажите фактический metavar='value' и он будет отображать именно этот текст.):

# without metavar specified:
-c, --chunksize CHUNKSIZE
                chunk size in bits
# with metavar specified:
-c, --chunksize some_metavar
                chunk size in bits

И код для класса и воспроизводящий два вывода:

import argparse
# 2.7-3.2
class SingleMetavarHelpFormatter(argparse.HelpFormatter):
    def _format_action_invocation(self, action):
        if not action.option_strings:
            metavar, = self._metavar_formatter(action, action.dest)(1)
            return metavar

        else:
            parts = []

            # if the Optional doesn't take a value, format is:
            #    -s, --long
            if action.nargs == 0:
                parts.extend(action.option_strings)

            # if the Optional takes a value, format is:
            #    -s ARGS, --long ARGS
            else:
                default = action.dest.upper()
                args_string = self._format_args(action, default)

                ## THIS IS THE PART REPLACED
                #~ for option_string in action.option_strings:
                    #~ parts.append('%s %s' % (option_string, args_string)) ### this is change
                ## /SECTION REPLACED

                ## NEW CODE:
                parts.extend(action.option_strings)
                parts[-1] += ' %s' % args_string
                ## /NEW CODE
            return ', '.join(parts)


parser = argparse.ArgumentParser(
    prog='PROG',
    formatter_class=SingleMetavarHelpFormatter
    )

parser.add_argument('-c', '--chunksize', type=int, help='no metavar specified')
parser.add_argument('-w', '--with_metavar', type=int, help='metavar specified', metavar='some_metavar')

parser.print_help()

изменить: чтобы вообще не отображать метапеременную, вы можете передать пустую строку в метапеременную:

parser.add_argument('-e', '--with_empty_metavar', type=int, help='empty metavar specified', metavar='')

Разница между выполнением этого с исходным классом и новым классом заключается в отсутствии дополнительного символа пробела после синтаксиса короткой команды.

#usage: PROG [-h] [-c CHUNKSIZE] [-w some_metavar] [-e]
#
#optional arguments:
#  -h, --help            show this help message and exit
#  -c CHUNKSIZE, --chunksize CHUNKSIZE
#                        no metavar specified
#  -w some_metavar, --with_metavar some_metavar
#                        metavar specified
#  -e, --with_empty_metavar
#                        empty metavar specified
person Nisan.H    schedule 06.06.2013
comment
Но зачем мне с самого начала иметь этот метавар? Если я посмотрю на типичные справочные сообщения в приложениях командной строки Linux, я не увижу эту строку metavar. - person bug; 07.06.2013
comment
Если вы передадите пустую строку в качестве метавара, то это то, что будет отображаться. Я включил это в редактирование. - person Nisan.H; 07.06.2013
comment
Спасибо, так что я мог бы написать свой собственный форматер, чтобы сделать эту работу. Я до сих пор не понимаю, почему это должно быть таким громоздким и почему это не поведение по умолчанию. - person bug; 10.06.2013
comment
Без какого-либо особого опыта разработки этого модуля или стандартов справочных сообщений в приложениях командной строки Linux мне кажется довольно естественным, что команда, принимающая параметр, будет отображать некоторый параметр-заполнитель для обозначения его позиции (а иногда и типа). .. Как бы то ни было, именно поэтому мне так нравится Python — очень легко изменить такое встроенное поведение в соответствии с вашими потребностями. - person Nisan.H; 10.06.2013

Что касается вашего вопроса о назначении прописных букв metavar, в документации говорится:

Один необязательный аргумент --foo, за которым должен следовать один аргумент командной строки, будет называться FOO.

Это объяснение, но мне пришлось прочитать его много раз, чтобы понять, что это просто означает, что FOO — это напоминание о предоставлении аргумента, где значение аргумента = FOO. Итак, используя более полезный пример, чем foo:

# --days DAYS   <-- from an imaginary help page
--days 365  # for a year; DAYS=365
--days 7    # for a week; DAYS=7 
person HFBrowning    schedule 20.05.2021