8.13。 列挙型 —列挙のサポート
バージョン3.4の新機能。
ソースコード: :source: `Lib / enum.py`
列挙型は、一意の定数値にバインドされたシンボリック名(メンバー)のセットです。 列挙内では、メンバーをIDで比較したり、列挙自体を繰り返し実行したりできます。
8.13.1。 モジュールの内容
このモジュールは、名前と値の一意のセットを定義するために使用できる4つの列挙クラスを定義します: Enum 、 IntEnum 、 Flag 、および IntFlag [X168X ]。 また、1つのデコレータ unique()と1つのヘルパー auto も定義します。
- class enum.Enum
- 列挙型定数を作成するための基本クラス。 別の構築構文については、セクション機能API を参照してください。
- class enum.IntEnum
- int のサブクラスでもある列挙型定数を作成するための基本クラス。
- class enum.IntFlag
- IntFlag メンバーシップを失うことなく、ビット演算子を使用して組み合わせることができる列挙型定数を作成するための基本クラス。 IntFlag メンバーは、 int のサブクラスでもあります。
- class enum.Flag
- Flag メンバーシップを失うことなく、ビット演算を使用して組み合わせることができる列挙型定数を作成するための基本クラス。
- enum.unique()
- 1つの名前のみが任意の1つの値にバインドされることを保証する列挙型クラスデコレータ。
- class enum.auto
- インスタンスは、列挙型メンバーの適切な値に置き換えられます。
バージョン3.6の新機能: Flag
、IntFlag
、auto
8.13.2。 列挙型の作成
列挙型は class 構文を使用して作成されるため、読み取りと書き込みが簡単です。 別の作成方法については、 Functional API で説明されています。 列挙型を定義するには、 Enum を次のようにサブクラス化します。
ノート
列挙型メンバー値
メンバー値は、 int 、 str などの任意の値にすることができます。 正確な値が重要でない場合は、 auto インスタンスを使用でき、適切な値が選択されます。 auto を他の値と混合する場合は、注意が必要です。
ノート
命名法
- クラス
Color
は、列挙型(または列挙型)です。 - 属性
Color.RED
、Color.GREEN
などは、列挙型メンバー(または列挙型メンバー)であり、機能的に定数です。 - 列挙型メンバーには名前と値があります(
Color.RED
の名前はRED
、Color.BLUE
の値は3
など)
列挙型メンバーには、人間が読める形式の文字列表現があります。
…彼らのrepr
にはより多くの情報があります:
列挙型メンバーの type は、それが属する列挙型です。
列挙型メンバーには、アイテム名だけを含むプロパティもあります。
列挙は、定義順に反復をサポートします。
列挙型メンバーはハッシュ可能であるため、辞書やセットで使用できます。
8.13.3。 列挙型メンバーとその属性へのプログラムによるアクセス
プログラムで列挙のメンバーにアクセスすると便利な場合があります(つまり、 プログラムの作成時に正確な色がわからないためにColor.RED
が機能しない状況)。 Enum
は、次のようなアクセスを許可します。
name で列挙型メンバーにアクセスする場合は、アイテムアクセスを使用します。
列挙型メンバーがあり、そのname
またはvalue
が必要な場合:
8.13.4。 列挙型メンバーと値の複製
同じ名前の2つの列挙型メンバーを持つことは無効です:
ただし、2つの列挙型メンバーは同じ値を持つことができます。 同じ値を持つ2つのメンバーAとBが与えられた場合(そしてAが最初に定義された場合)、BはAのエイリアスです。 AとBの値を値で検索すると、Aが返されます。 Bの名前によるルックアップでも、Aが返されます。
ノート
すでに定義されている属性(別のメンバー、メソッドなど)と同じ名前のメンバーを作成しようとしたり、メンバーと同じ名前の属性を作成しようとしたりすることはできません。
8.13.5。 一意の列挙値を確保する
デフォルトでは、列挙は同じ値のエイリアスとして複数の名前を許可します。 この動作が望ましくない場合は、次のデコレータを使用して、各値が列挙で1回だけ使用されるようにすることができます。
- @enum.unique
列挙専用の class デコレータ。 列挙型の__members__
を検索して、見つかったエイリアスを収集します。 見つかった場合、 ValueError が詳細とともに表示されます。
8.13.7。 反復
列挙型のメンバーを反復処理しても、エイリアスは提供されません。
特別な属性__members__
は、名前をメンバーにマッピングする順序付けられた辞書です。 これには、エイリアスを含む、列挙で定義されたすべての名前が含まれます。
__members__
属性は、列挙メンバーへの詳細なプログラムアクセスに使用できます。 たとえば、すべてのエイリアスを検索します。
8.13.8。 比較
列挙型メンバーはIDによって比較されます。
列挙値間の順序付き比較はサポートされていません。 列挙型メンバーは整数ではありません(ただし、以下の IntEnum を参照してください)。
ただし、同等性の比較は次のように定義されています。
非列挙値との比較は、常に等しくないものと比較されます(ここでも、 IntEnum は、異なる動作をするように明示的に設計されています。以下を参照してください)。
8.13.9。 許可されたメンバーと列挙の属性
上記の例では、列挙値に整数を使用しています。 整数の使用は短くて便利ですが( Functional API によってデフォルトで提供されます)、厳密には強制されません。 大多数のユースケースでは、列挙型の実際の値が何であるかは気にしません。 ただし、値が重要である場合、列挙には任意の値を指定できます。
列挙型はPythonクラスであり、通常どおりメソッドと特別なメソッドを持つことができます。 この列挙がある場合:
それで:
許可されるルールは次のとおりです。単一のアンダースコアで開始および終了する名前は列挙型によって予約されており、使用できません。 特別なメソッド(__str__()
、__add__()
など)と記述子(メソッドも記述子です)を除いて、列挙内で定義された他のすべての属性がこの列挙のメンバーになります。
注:列挙型で__new__()
または__init__()
、あるいはその両方が定義されている場合、列挙型メンバーに指定された値はすべてこれらのメソッドに渡されます。 例については、 Planet を参照してください。
8.13.10。 列挙型の制限されたサブクラス化
列挙型のサブクラス化は、列挙型でメンバーが定義されていない場合にのみ許可されます。 したがって、これは禁止されています。
しかし、これは許可されています:
メンバーを定義する列挙型のサブクラス化を許可すると、タイプとインスタンスのいくつかの重要な不変条件に違反することになります。 一方、列挙型のグループ間でいくつかの共通の動作を共有できるようにすることは理にかなっています。 (例については、 OrderedEnum を参照してください。)
8.13.11。 酸洗い
列挙は、ピクル化およびピクルス解除できます。
ピクルス化の通常の制限が適用されます。ピクルス化解除ではモジュールからインポート可能である必要があるため、ピクルス可能な列挙型はモジュールのトップレベルで定義する必要があります。
ノート
pickleプロトコルバージョン4を使用すると、他のクラスにネストされた列挙型を簡単にpickle化できます。
列挙型クラスで__reduce_ex__()
を定義することにより、列挙型メンバーのピクルス/アンピクルスの方法を変更できます。
8.13.12。 機能API
Enum クラスは呼び出し可能であり、次の機能APIを提供します。
このAPIのセマンティクスは、 namedtuple に似ています。 Enum の呼び出しの最初の引数は、列挙の名前です。
2番目の引数は、列挙メンバー名の source です。 これは、空白で区切られた名前の文字列、名前のシーケンス、キーと値のペアを持つ2つのタプルのシーケンス、またはマッピング(例: 辞書)名前から値へ。 最後の2つのオプションを使用すると、列挙に任意の値を割り当てることができます。 その他は、1から始まる増加する整数を自動割り当てします(start
パラメーターを使用して別の開始値を指定します)。 Enum から派生した新しいクラスが返されます。 つまり、上記のAnimal
への割り当ては次のようになります。
0
ではなく1
を開始番号としてデフォルト設定する理由は、0
がブール値の意味でFalse
であるためですが、列挙型メンバーはすべて[ X164X] 。
機能APIで作成された列挙型のピクルス化は、フレームスタックの実装の詳細を使用して、列挙型が作成されているモジュールを特定しようとするため、注意が必要な場合があります(例: 別のモジュールでユーティリティ関数を使用すると失敗し、IronPythonまたはJythonでも機能しない可能性があります)。 解決策は、次のようにモジュール名を明示的に指定することです。
警告
module
が指定されておらず、Enumがそれが何であるかを判別できない場合、新しいEnumメンバーは選択できなくなりません。 エラーをソースに近づけるために、pickle化は無効になります。
新しいpickleプロトコル4も、状況によっては、 __ qualname __ がpickleがクラスを見つけることができる場所に設定されていることに依存しています。 たとえば、クラスがグローバルスコープのSomeDataクラスで使用可能になった場合:
完全な署名は次のとおりです。
- 価値
新しいEnumクラスがその名前として記録するもの。
- 名前
列挙型メンバー。 これは、空白またはコンマ区切りの文字列にすることができます(特に指定がない限り、値は1から始まります)。
または名前のイテレータ:
または(名前、値)ペアのイテレータ:
またはマッピング:
- モジュール
新しいEnumクラスを見つけることができるモジュールの名前。
- qualname
モジュール内の新しいEnumクラスが見つかります。
- タイプ
新しいEnumクラスにミックスインするタイプ。
- 始める
名前のみが渡された場合にカウントを開始する番号。
バージョン3.5で変更: start パラメーターが追加されました。
8.13.13。 派生列挙
8.13.13.1。 IntEnum
提供される Enum の最初のバリエーションも、 int のサブクラスです。 IntEnum のメンバーは整数と比較できます。 拡張により、異なるタイプの整数列挙も互いに比較できます。
ただし、標準の Enum 列挙型と比較することはできません。
IntEnum 値は、期待する他の方法で整数のように動作します。
8.13.13.2。 IntFlag
提供される Enum の次のバリエーションである IntFlag も、 int に基づいています。 違いは IntFlag メンバーはビット演算子(&、|、^、〜)を使用して組み合わせることができ、結果は引き続き IntFlag メンバー。 ただし、名前が示すように、 IntFlag メンバーも int をサブクラス化し、 int が使用されている場所ならどこでも使用できます。 ビット単位の操作以外の IntFlag メンバーに対する操作は、 IntFlag メンバーシップを失います。
バージョン3.6の新機能。
サンプル IntFlag クラス:
組み合わせに名前を付けることもできます。
IntFlag と Enum のもう1つの重要な違いは、フラグが設定されていない場合(値が0の場合)、ブール評価は False であるということです。
IntFlag メンバーも int のサブクラスであるため、次のように組み合わせることができます。
8.13.13.3。 国旗
最後のバリエーションは Flag です。 お気に入り IntFlag 、 国旗メンバーは、ビット演算子(&、|、^、〜)を使用して組み合わせることができます。 IntFlag とは異なり、他の Flag 列挙や、 int と組み合わせたり、比較したりすることはできません。 値を直接指定することも可能ですが、値として auto を使用し、 Flag に適切な値を選択させることをお勧めします。
バージョン3.6の新機能。
IntFlag と同様に、 Flag メンバーの組み合わせでフラグが設定されない場合、ブール評価は False です。
個々のフラグは2の累乗(1、2、4、8、…)の値を持つ必要がありますが、フラグの組み合わせは次のようにはなりません。
「フラグが設定されていない」条件に名前を付けても、ブール値は変更されません。
8.13.13.4。 その他
IntEnum は enum モジュールの一部ですが、独立して実装するのは非常に簡単です。
これは、同様の派生列挙を定義する方法を示しています。 たとえば、 int の代わりに str を混合するStrEnum
。
いくつかのルール:
- Enum をサブクラス化する場合、上記の IntEnum の例のように、ミックスインタイプは Enum 自体の前にベースのシーケンスで表示される必要があります。
- Enum には任意のタイプのメンバーを含めることができますが、追加のタイプを混在させると、すべてのメンバーにそのタイプの値が必要になります。 上記の int 。 この制限は、メソッドを追加するだけで、 int や str などの別のデータ型を指定しないミックスインには適用されません。
- 別のデータ型が混在している場合、
value
属性は列挙型メンバー自体と同じではありませんが、同等であり、同等に比較されます。 - %スタイルのフォーマット:%s および%r は、それぞれ Enum クラスの
__str__()
および__repr__()
を呼び出します。 他のコード(IntEnumの%i や%h など)は、列挙型メンバーを混合型として扱います。 - フォーマットされた文字列リテラル、 str.format()、および format()は、混合型の
__format__()
を使用します。 Enum クラスの str()または repr()が必要な場合は、!s または!r を使用します。 ]フォーマットコード。
8.13.14。 興味深い例
Enum 、 IntEnum 、 IntFlag 、および Flag は、ユースケースの大部分をカバーすることが期待されていますが、すべてをカバーすることはできません。 これは、直接使用できる、または独自の列挙を作成するための例として使用できる、いくつかの異なるタイプの列挙のレシピです。
8.13.14.1。 値を省略する
多くのユースケースでは、列挙型の実際の値が何であるかは気にしません。 このタイプの単純な列挙を定義するには、いくつかの方法があります。
- 値に auto のインスタンスを使用します
- オブジェクトのインスタンスを値として使用します
- 値として説明文字列を使用する
- タプルを値として使用し、カスタム
__new__()
を使用して、タプルを int 値に置き換えます。
これらの方法のいずれかを使用すると、これらの値は重要ではないことをユーザーに示し、残りのメンバーの番号を付け直すことなく、メンバーを追加、削除、または並べ替えることができます。
どちらの方法を選択する場合でも、(重要でない)値も非表示にする repr()を提供する必要があります。
8.13.14.1.3。 説明的な文字列を使用する
値として文字列を使用すると、次のようになります。
8.13.14.1.4。 カスタムを使用する__new__()
自動番号付け__new__()
を使用すると、次のようになります。
ノート
__new__()
メソッドは、定義されている場合、Enumメンバーの作成中に使用されます。 次に、既存のメンバーを検索するためにクラスの作成後に使用されるEnumの__new__()
に置き換えられます。
8.13.14.3。 DuplicateFreeEnum
エイリアスを作成する代わりに重複するメンバー名が見つかった場合、エラーが発生します。
ノート
これは、列挙型をサブクラス化して他の動作を追加または変更したり、エイリアスを禁止したりする場合に便利な例です。 必要な変更がエイリアスの禁止のみである場合は、代わりに unique()デコレータを使用できます。
8.13.14.4。 星
__new__()
または__init__()
が定義されている場合、列挙型メンバーの値はこれらのメソッドに渡されます。
8.13.15。 列挙型はどのように異なりますか?
列挙型には、派生した列挙型クラスとそのインスタンス(メンバー)の両方の多くの側面に影響を与えるカスタムメタクラスがあります。
8.13.15.1。 列挙型クラス
EnumMeta
メタクラスは、__contains__()
、__dir__()
、__iter__()
、および列挙型[X151X ] Color の list(Color)や some_varなど、一般的なクラスで失敗するクラス。 EnumMeta
は、最後の Enum クラスの他のさまざまなメソッド(__new__()
、__getnewargs__()
、__str__()
など)が正しいことを確認する責任があります。および__repr__()
)。
8.13.15.2。 列挙型メンバー(別名インスタンス)
列挙型メンバーの最も興味深い点は、それらがシングルトンであるということです。 EnumMeta
は、 Enum クラス自体を作成している間にそれらをすべて作成し、カスタム__new__()
を配置して、新しいものがインスタンス化されないようにします。既存のメンバーインスタンス。
8.13.15.3。 より細かいポイント
8.13.15.3.1。 サポートされています__dunder__名前
__members__
は、member_name
:member
アイテムのOrderedDict
です。 クラスでのみご利用いただけます。
__new__()
は、指定されている場合、列挙型メンバーを作成して返す必要があります。 メンバーの_value_
を適切に設定することも非常に良い考えです。 すべてのメンバーが作成されると、それは使用されなくなります。
8.13.15.3.2。 サポートされています_sunder_名前
_name_
–メンバーの名前_value_
–メンバーの値。__new__
で設定/変更できます_missing_
–値が見つからない場合に使用されるルックアップ関数。 上書きされる可能性があります_order_
–メンバーの順序が一貫していることを確認するためにPython 2/3コードで使用されます(クラス属性、クラス作成中に削除されます)_generate_next_value_
– Functional API および auto によって使用され、列挙型メンバーの適切な値を取得します。 上書きされる可能性があります
バージョン3.6の新機能: _missing_
、_order_
、_generate_next_value_
Python 2 / Python 3コードの同期を維持するために、_order_
属性を指定できます。 列挙の実際の順序と照合され、2つが一致しない場合はエラーが発生します。
ノート
Python 2コードでは、_order_
属性が必要です。これは、定義の順序が記録される前に失われるためです。
8.13.15.3.3。 Enumメンバータイプ
Enum メンバーは、 Enum クラスのインスタンスであり、通常はEnumClass.member
としてアクセスされます。 特定の状況下では、EnumClass.member.member
としてアクセスすることもできますが、ルックアップが失敗したり、さらに悪いことに、探している Enum メンバー以外のものを返す可能性があるため、これを実行しないでください(これはメンバーにすべて大文字の名前を使用するもう1つの理由):
バージョン3.5で変更されました。
8.13.15.3.4。 のブール値Enumクラスとメンバー
Enum 以外のタイプ( int 、 str など)と混合された Enum メンバーは、混合に従って評価されます。 -タイプのルールで; それ以外の場合、すべてのメンバーは True と評価されます。 独自の列挙型のブール評価をメンバーの値に依存させるには、クラスに以下を追加します。
8.13.15.3.5。 Enumメソッドを持つクラス
上記の Planet クラスのように、 Enum サブクラスに追加のメソッドを指定すると、それらのメソッドはメンバーの dir()に表示されますが、クラス:
8.13.15.3.6。 のメンバーを組み合わせるFlag
Flagメンバーの組み合わせに名前が付けられていない場合、 repr()には、値に含まれるすべての名前付きフラグとすべての名前付きフラグの組み合わせが含まれます。