PythonでintをEnumに変換する方法は?


96

Python 2.7.6で(バックポートenum34を介して)新しい列挙型機能を使用する。

次の定義がある場合、intを対応するEnum値に変換するにはどうすればよいですか?

from enum import Enum

class Fruit(Enum):
    Apple = 4
    Orange = 5
    Pear = 6

変換を行うために一連のifステートメントを手作りできることは知っていますが、変換する簡単なpythonicの方法はありますか?基本的に、列挙値を返す関数ConvertIntToFruit(int)が必要です。

私のユースケースは、各レコードをオブジェクトに読み込んでいるレコードのcsvファイルがあることです。ファイルフィールドの1つは、列挙型を表す整数フィールドです。オブジェクトにデータを入力しているときに、その整数フィールドをファイルからオブジェクト内の対応するEnum値に変換したいと思います。

回答:


165

Enumクラスを「呼び出す」:

Fruit(5)

オンにする5Fruit.Orange

>>> from enum import Enum
>>> class Fruit(Enum):
...     Apple = 4
...     Orange = 5
...     Pear = 6
... 
>>> Fruit(5)
<Fruit.Orange: 5>

ドキュメントの列挙メンバーとその属性セクションプログラムによるアクセスから

プログラムで列挙型のメンバーにアクセスすると便利な場合があります(つまりColor.red、プログラムの作成時に正確な色がわからないためにアクセスできない状況)。Enumそのようなアクセスを許可します:

>>> Color(1)
<Color.red: 1>
>>> Color(3)
<Color.blue: 3>

関連する注記:列挙型メンバーの名前を含む文字列値をマップするには、サブスクリプションを使用します。

>>> s = 'Apple'
>>> Fruit[s]
<Fruit.Apple: 4>

ドキュメントを読み直していたので、これを受け取ってくれてありがとう。私の最初のスキムスルーでははっきりしませんでした。また、文字列を使用してみましたが、列挙値が文字列の場合にも機能することを確認しました。任意のオブジェクト値を想定しています。
ユーザー

非常に良いので、変換は値によるものです。列挙型リストをフィルタリングして名前属性を照合するためのリスト内包表記以外の名前による類似物はありますか?
jxramos 2017年

4
@jxramosは私の回答のドキュメントリンクをたどっていますが、そこで明示的に説明されています。アイテムアクセスを使用する:Fruit['Orange']
MartijnPieters

ビンゴ、とてもすごい!私はページを検索convertcoercecastしかし、何もヒットしませんでした。魔法があったように見えaccess enum members by name, use item accessます。Perfecto、どうもありがとう。この構文でコードをクリーンアップします。
jxramos 2017年

さらにクールなのは"foobar" in Fruit.__members__、メンバーシップをテストしたりFruit.get( 'foobar', Fruit.Orange )、デフォルトのEnumフレーバーを取得したりするために使用できることです。私のコードは、以前に作成したこれらのアクセサリルックアップスキャフォールドをすべて削除することで、はるかに単純化されたように見えます。
jxramos 2017年

1

簡単に言うと、を呼び出してint値をに変換し、その後、オブジェクトのにアクセスすることだと思います。EnumEnumType(int_value)nameEnum

my_fruit_from_int = Fruit(5) #convert to int
fruit_name = my_fruit_from_int.name #get the name
print(fruit_name) #Orange will be printed here

または関数として:

def convert_int_to_fruit(int_value):
    try:
        my_fruit_from_int = Fruit(int_value)
        return my_fruit_from_int.name
    except:
        return None

-1

単一の参照から値のペアのいずれかの部分にアクセスできるように、同様の何かが必要でした。バニラバージョン:

#!/usr/bin/env python3


from enum import IntEnum


class EnumDemo(IntEnum):
    ENUM_ZERO       = 0
    ENUM_ONE        = 1
    ENUM_TWO        = 2
    ENUM_THREE      = 3
    ENUM_INVALID    = 4


#endclass.


print('Passes')
print('1) %d'%(EnumDemo['ENUM_TWO']))
print('2) %s'%(EnumDemo['ENUM_TWO']))
print('3) %s'%(EnumDemo.ENUM_TWO.name))
print('4) %d'%(EnumDemo.ENUM_TWO))
print()


print('Fails')
print('1) %d'%(EnumDemo.ENUM_TWOa))

失敗すると、予想どおりに例外がスローされます。

より堅牢なバージョン:

#!/usr/bin/env python3


class EnumDemo():


    enumeration =   (
                        'ENUM_ZERO',    # 0.
                        'ENUM_ONE',     # 1.
                        'ENUM_TWO',     # 2.
                        'ENUM_THREE',   # 3.
                        'ENUM_INVALID'  # 4.
                    )


    def name(self, val):
        try:

            name = self.enumeration[val]
        except IndexError:

            # Always return last tuple.
            name = self.enumeration[len(self.enumeration) - 1]

        return name


    def number(self, val):
        try:

            index = self.enumeration.index(val)
        except (TypeError, ValueError):

            # Always return last tuple.
            index = (len(self.enumeration) - 1)

        return index


#endclass.


print('Passes')
print('1) %d'%(EnumDemo().number('ENUM_TWO')))
print('2) %s'%(EnumDemo().number('ENUM_TWO')))
print('3) %s'%(EnumDemo().name(1)))
print('4) %s'%(EnumDemo().enumeration[1]))
print()
print('Fails')
print('1) %d'%(EnumDemo().number('ENUM_THREEa')))
print('2) %s'%(EnumDemo().number('ENUM_THREEa')))
print('3) %s'%(EnumDemo().name(11)))
print('4) %s'%(EnumDemo().enumeration[-1]))

正しく使用されていない場合、これは例外の作成を回避し、代わりに障害表示を返します。これを行うためのよりPythonicな方法は、「なし」を返すことですが、私の特定のアプリケーションはテキストを直接使用します。


列挙型インスタンスでメソッド__int____str__メソッドを定義しないのはなぜですか?
ティム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.