argparse での Enum 引数のサポート 質問する

argparse での Enum 引数のサポート 質問する

このパターンよりも、列挙型を argparse 引数の型としてサポートするより良い方法はありますか?

class SomeEnum(Enum):
    ONE = 1
    TWO = 2

parser.add_argument('some_val', type=str, default='one',
                    choices=[i.name.lower() for i in SomeEnum])
...
args.some_val = SomeEnum[args.some_val.upper()]

ベストアンサー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

のヘルプ出力に の人間が判読できる形式 (値) を含めるには、を定義する__str__必要があることに注意してください。ArgumentParserColor

呼び出しの例:

=> 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}

OP の質問では値として整数が指定されているため、その場合に機能するわずかに変更されたバージョンを次に示します (コマンドライン引数として、値ではなく列挙名を使用します)。

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))

おすすめ記事