Ответ 1
Я вижу, что это старый вопрос, но я столкнулся с одной и той же проблемой (Python 2.7), и вот как я ее решил:
from argparse import ArgumentParser
from enum import Enum
class Color(Enum):
red = 'red'
blue = 'blue'
green = 'green'
def __str__(self):
return self.value
parser = ArgumentParser()
parser.add_argument('color', type=Color, choices=list(Color))
opts = parser.parse_args()
print 'your color was:', opts.color
Обратите внимание, что для определения ArgumentParser
для вывода ArgumentParser
требуется указать __str__
, чтобы включить считываемый человеком (значения) Color
.
Некоторые примеры запросов:
=> python enumtest.py blue
your color was: blue
=> python enumtest.py not-a-color
usage: enumtest.py [-h] {blue,green,red}
enumtest.py: error: argument color: invalid Color value: 'not-a-color'
=> python enumtest.py -h
usage: enumtest.py [-h] {blue,green,red}
positional arguments:
{blue,green,red}
Поскольку вопрос ОП задает целые числа как значения, вот немного модифицированная версия, которая работает в этом случае (с использованием имен перечислений, а не значений, как указано в командной строке):
class Color(Enum):
red = 1
blue = 2
green = 3
def __str__(self):
return self.name
parser = ArgumentParser()
parser.add_argument('color', type=lambda color: Color[color], choices=list(Color))
Единственный недостаток заключается в том, что плохой параметр вызывает уродливое KeyError
. Это легко решить, добавив еще немного кода, превратив лямбда в правильную функцию.
class Color(Enum):
red = 1
blue = 2
green = 3
def __str__(self):
return self.name
@staticmethod
def from_string(s):
try:
return Color[s]
except KeyError:
raise ValueError()
parser = ArgumentParser()
parser.add_argument('color', type=Color.from_string, choices=list(Color))