widzę jest to stara sprawa, ale ja po prostu natknął się na ten sam problem (Python 2.7) i oto jak I rozwiązać go:
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
Zauważ, że definiowanie __str__
jest wymagany do uzyskania ArgumentParser
' s pomoc wyjściowa do włączenia czytelne dla człowieka (wartości) z Color
.
Niektóre przykładowe wywołania:
=> 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}
Ponieważ zapytania podano liczb PO jako wartości, tutaj jest nieco zmodyfikowaną wersją, która działa w tym przypadku (używając nazwy enum, zamiast wartości, jak args linii komend):
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))
Jedyną wadą jest fakt, że zły parametr powoduje brzydki KeyError
. Można to łatwo rozwiązać, dodając nieco więcej kodu, przekształcając lambdę w odpowiednią funkcję.
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))
Pojawił się wniosek o "Enum" na błędy/problemy w Pythonie. Nie przypominam sobie zbytniego entuzjazmu dla dodatkowej specjalnej obsługi. Wybory takie jak twoje są jednym ze sposobów. Inną jest niestandardowa funkcja 'type'. To może sprawdzić i przekonwertować. Podejrzewam, że znasz Enums bardziej niż ja. – hpaulj
Zastanawiam się przez chwilę, czy byłoby możliwe wyprowadzenie niestandardowej Enum, która zachowałaby się zgodnie z oczekiwaniami, gdy ustawiona jako 'type =' –
Parametr 'type' jest funkcją/wywoływalną. Napisz własny, który bierze ciąg i coś z nim robi. Typy wspólne, 'int' i' float' są standardowymi funkcjami, które wykonują 'int (" 123 ")' lub 'float (" 12.3 ")'. – hpaulj