Как Вы обрабатываете опции, которые не могут использоваться вместе (использующий OptionParser)?

Мой сценарий Python (для списков ожидающих выполнения задач) запускается с командной строки как это:

todo [options] <command> [command-options]

Некоторые опции не могут использоваться вместе, например

todo add --pos=3 --end "Ask Stackoverflow"

указал бы и третье положение и конец списка. Аналогично

todo list --brief --informative

перепутал бы мою программу о том, чтобы быть кратким или информативным. Так как я хочу иметь вполне мощный контроль опцией, случаи как они будут набором, и новые, конечно, возникнут в будущем. Если пользователи передают плохую комбинацию опций, я хочу дать информативное сообщение, предпочтительно наряду со справкой использования, обеспеченной optparse. В настоящее время я обрабатываю это с, если еще оператор, который я нахожу действительно ужасными и плохими. Моя мечта состоит в том, чтобы иметь что-то вроде этого в моем коде:

parser.set_not_allowed(combination=["--pos", "--end"], 
                       message="--pos and --end can not be used together")

и OptionParser использовал бы это при парсинге опций.

Так как это не существует насколько я знаю, я спрашиваю ТАКИМ ОБРАЗОМ сообщество: Как Вы обрабатываете это?

7
задан Joel 28 April 2010 в 14:04
поделиться

1 ответ

Возможно путем расширения optparse.OptionParser :

class Conflict(object):
    __slots__ = ("combination", "message", "parser")

    def __init__(self, combination, message, parser):
        self.combination = combination
        self.message = str(message)
        self.parser = parser

    def accepts(self, options):
        count = sum(1 for option in self.combination if hasattr(options, option))
        return count <= 1

class ConflictError(Exception):
    def __init__(self, conflict):
        self.conflict = conflict

    def __str__(self):
        return self.conflict.message

class MyOptionParser(optparse.OptionParser):
    def __init__(self, *args, **kwds):
        optparse.OptionParser.__init__(self, *args, **kwds)
        self.conflicts = []

    def set_not_allowed(self, combination, message):
        self.conflicts.append(Conflict(combination, message, self))

    def parse_args(self, *args, **kwds):
        # Force-ignore the default values and parse the arguments first
        kwds2 = dict(kwds)
        kwds2["values"] = optparse.Values()
        options, _ = optparse.OptionParser.parse_args(self, *args, **kwds2)

        # Check for conflicts
        for conflict in self.conflicts:
            if not conflict.accepts(options):
                raise ConflictError(conflict)

        # Parse the arguments once again, now with defaults
        return optparse.OptionParser.parse_args(self, *args, **kwds)

Затем вы можете обработать ConflictError , где вы вызываете parse_args :

try:
    options, args = parser.parse_args()
except ConflictError as err:
    parser.error(err.message)
6
ответ дан 7 December 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: