列挙型 HOWTO
************

"Enum" は、ユニークな値に束縛されたシンボル名の集合です。グローバル変
数に似ていますが、 "repr()" がより便利だったり、グルーピングの機能、型
安全などいくつかの機能があります。

これらは、限られた選択肢の値の一つを取る変数がある場合に便利です。例え
ば、曜日情報があります:

   >>> from enum import Enum
   >>> class Weekday(Enum):
   ...     MONDAY = 1
   ...     TUESDAY = 2
   ...     WEDNESDAY = 3
   ...     THURSDAY = 4
   ...     FRIDAY = 5
   ...     SATURDAY = 6
   ...     SUNDAY = 7

あるいは、RGB三原色でも構いません:

   >>> from enum import Enum
   >>> class Color(Enum):
   ...     RED = 1
   ...     GREEN = 2
   ...     BLUE = 3

ご覧の通り、 "Enum" の作成は "Enum" 自体を継承するクラスを作成するのと
同じくらい簡単です。

注釈:

  Enumメンバーは大文字/小文字？列挙型は定数を表すために使われるため、
  また mixin クラスのメソッドや属性との名前の衝突の問題を回避するため
  、メンバには UPPER_CASE の名前を使うことが強く推奨されており、例でも
  このスタイルを用います。

列挙型の性質によって、メンバの値は重要な場合とそうでない場合があります
が、いずれの場合でも、その値は対応するメンバを取得するのに使えます:

   >>> Weekday(3)
   <Weekday.WEDNESDAY: 3>

ご覧の通り、メンバの "repr()" は列挙型の名前、メンバの名前、そして値を
表示します。メンバの "str()" は列挙型の名前とメンバの名前のみを表示し
ます。

   >>> print(Weekday.THURSDAY)
   Weekday.THURSDAY

列挙型のメンバの型はそのメンバの属する列挙型です:

   >>> type(Weekday.MONDAY)
   <enum 'Weekday'>
   >>> isinstance(Weekday.FRIDAY, Weekday)
   True

Enum members have an attribute that contains just their "name":

   >>> print(Weekday.TUESDAY.name)
   TUESDAY

Likewise, they have an attribute for their "value":

   >>> Weekday.WEDNESDAY.value
   3

Unlike many languages that treat enumerations solely as name/value
pairs, Python Enums can have behavior added.  For example,
"datetime.date" has two methods for returning the weekday: "weekday()"
and "isoweekday()". The difference is that one of them counts from 0-6
and the other from 1-7. Rather than keep track of that ourselves we
can add a method to the "Weekday" enum to extract the day from the
"date" instance and return the matching enum member:

   @classmethod
   def from_date(cls, date):
       return cls(date.isoweekday())

The complete "Weekday" enum now looks like this:

   >>> class Weekday(Enum):
   ...     MONDAY = 1
   ...     TUESDAY = 2
   ...     WEDNESDAY = 3
   ...     THURSDAY = 4
   ...     FRIDAY = 5
   ...     SATURDAY = 6
   ...     SUNDAY = 7
   ...     #
   ...     @classmethod
   ...     def from_date(cls, date):
   ...         return cls(date.isoweekday())

さて、これで今日が何曜日か調べることができます！ 見てみましょう:

   >>> import datetime as dt
   >>> Weekday.from_date(dt.date.today())
   <Weekday.TUESDAY: 2>

もちろん、あなたがこれを読んでいるのが他の曜日ならば、その曜日が代わり
に表示されます。

This "Weekday" enum is great if our variable only needs one day, but
what if we need several?  Maybe we're writing a function to plot
chores during a week, and don't want to use a "list" -- we could use a
different type of "Enum":

   >>> from enum import Flag
   >>> class Weekday(Flag):
   ...     MONDAY = 1
   ...     TUESDAY = 2
   ...     WEDNESDAY = 4
   ...     THURSDAY = 8
   ...     FRIDAY = 16
   ...     SATURDAY = 32
   ...     SUNDAY = 64

ここでは2つの変更が行われています。"Flag" を継承している点と、値がすべ
て2の累乗である点です。

Just like the original "Weekday" enum above, we can have a single
selection:

   >>> first_week_day = Weekday.MONDAY
   >>> first_week_day
   <Weekday.MONDAY: 1>

ただし、"Flag" は複数のメンバーをひとつの変数にまとめることもできます:

   >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY
   >>> weekend
   <Weekday.SATURDAY|SUNDAY: 96>

"Flag" 変数は反復することもできます:

   >>> for day in weekend:
   ...     print(day)
   Weekday.SATURDAY
   Weekday.SUNDAY

さて、いくつかの家事を設定してみましょう:

   >>> chores_for_ethan = {
   ...     'feed the cat': Weekday.MONDAY | Weekday.WEDNESDAY | Weekday.FRIDAY,
   ...     'do the dishes': Weekday.TUESDAY | Weekday.THURSDAY,
   ...     'answer SO questions': Weekday.SATURDAY,
   ...     }

指定された日の家事を表示する関数も作成します:

   >>> def show_chores(chores, day):
   ...     for chore, days in chores.items():
   ...         if day in days:
   ...             print(chore)
   ...
   >>> show_chores(chores_for_ethan, Weekday.SATURDAY)
   answer SO questions

メンバーの実際の値が重要でない場合は、"auto()" を使用することで手間を
省くことができます:

   >>> from enum import auto
   >>> class Weekday(Flag):
   ...     MONDAY = auto()
   ...     TUESDAY = auto()
   ...     WEDNESDAY = auto()
   ...     THURSDAY = auto()
   ...     FRIDAY = auto()
   ...     SATURDAY = auto()
   ...     SUNDAY = auto()
   ...     WEEKEND = SATURDAY | SUNDAY


列挙型メンバーおよびそれらの属性へのプログラム的アクセス
========================================================

プログラム的にメンバーに番号でアクセスしたほうが便利な場合があります (
すなわち、プログラムを書いている時点で正確な色がまだわからなく、
"Color.RED" と書くのが無理な場合など)。 "Enum" ではそのようなアクセス
も可能です:

   >>> Color(1)
   <Color.RED: 1>
   >>> Color(3)
   <Color.BLUE: 3>

列挙型メンバーに *名前* でアクセスしたい場合はアイテムとしてアクセスで
きます:

   >>> Color['RED']
   <Color.RED: 1>
   >>> Color['GREEN']
   <Color.GREEN: 2>

If you have an enum member and need its "name" or "value":

   >>> member = Color.RED
   >>> member.name
   'RED'
   >>> member.value
   1


列挙型メンバーと値の重複
========================

同じ名前の列挙型メンバーを複数持つことはできません:

   >>> class Shape(Enum):
   ...     SQUARE = 2
   ...     SQUARE = 3
   ...
   Traceback (most recent call last):
   ...
   TypeError: 'SQUARE' already defined as 2

しかし、列挙型メンバー は、別の名前を持つことができます。  同じ値を持
つ "A" と``B`` が与えられた場合（そして "A" が先に定義されている場合）
、 "B" はメンバー "A" に対するエイリアスとなります。  "A" の値での検索
では、メンバー "A" が返されます。  "A" の名前での検索ではメンバー "A"
を返します。"B" の名前での検索も、メンバー "A" を返します:

   >>> class Shape(Enum):
   ...     SQUARE = 2
   ...     DIAMOND = 1
   ...     CIRCLE = 3
   ...     ALIAS_FOR_SQUARE = 2
   ...
   >>> Shape.SQUARE
   <Shape.SQUARE: 2>
   >>> Shape.ALIAS_FOR_SQUARE
   <Shape.SQUARE: 2>
   >>> Shape(2)
   <Shape.SQUARE: 2>

注釈:

  すでに定義されている属性と同じ名前のメンバー (一方がメンバーでもう一
  方がメソッド、など) の作成、あるいはメンバーと同じ名前の属性の作成は
  できません。


番号付けの値が一意であることの確認
==================================

デフォルトでは、列挙型は同じ値のエイリアスとして複数の名前を許容します
。この振る舞いを望まない場合は、 "unique()" デコレータを使用できます:

   >>> from enum import Enum, unique
   >>> @unique
   ... class Mistake(Enum):
   ...     ONE = 1
   ...     TWO = 2
   ...     THREE = 3
   ...     FOUR = 3
   ...
   Traceback (most recent call last):
   ...
   ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE


値の自動設定を使う
==================

正確な値が重要でない場合、 "auto" が使えます:

   >>> from enum import Enum, auto
   >>> class Color(Enum):
   ...     RED = auto()
   ...     BLUE = auto()
   ...     GREEN = auto()
   ...
   >>> [member.value for member in Color]
   [1, 2, 3]

The values are chosen by "_generate_next_value_()", which can be
overridden:

   >>> class AutoName(Enum):
   ...     @staticmethod
   ...     def _generate_next_value_(name, start, count, last_values):
   ...         return name
   ...
   >>> class Ordinal(AutoName):
   ...     NORTH = auto()
   ...     SOUTH = auto()
   ...     EAST = auto()
   ...     WEST = auto()
   ...
   >>> [member.value for member in Ordinal]
   ['NORTH', 'SOUTH', 'EAST', 'WEST']

注釈:

  The "_generate_next_value_()" method must be defined before any
  members.


イテレーション
==============

列挙型のメンバーのイテレートは別名をサポートしていません:

   >>> list(Shape)
   [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>]
   >>> list(Weekday)
   [<Weekday.MONDAY: 1>, <Weekday.TUESDAY: 2>, <Weekday.WEDNESDAY: 4>, <Weekday.THURSDAY: 8>, <Weekday.FRIDAY: 16>, <Weekday.SATURDAY: 32>, <Weekday.SUNDAY: 64>]

エイリアスである "Shape.ALIAS_FOR_SQUARE" と``Weekday.WEEKEND`` が表示
されていないことに注意してください。

特殊属性 "__members__" は読み出し専用で、順序を保持した、対応する名前
と列挙型メンバーのマッピングです。これには別名も含め、列挙されたすべて
の名前が入っています。

   >>> for name, member in Shape.__members__.items():
   ...     name, member
   ...
   ('SQUARE', <Shape.SQUARE: 2>)
   ('DIAMOND', <Shape.DIAMOND: 1>)
   ('CIRCLE', <Shape.CIRCLE: 3>)
   ('ALIAS_FOR_SQUARE', <Shape.SQUARE: 2>)

属性 "__members__" は列挙型メンバーへの詳細なアクセスに使用できます。
以下はすべての別名を探す例です:

   >>> [name for name, member in Shape.__members__.items() if member.name != name]
   ['ALIAS_FOR_SQUARE']

注釈:

  フラグのエイリアスには、 複数のフラグが設定された値（例えば "3"）や
  、 フラグが設定されていない値（例えば "0"）が含まれます。


比較
====

列挙型メンバーは同一性を比較できます:

   >>> Color.RED is Color.RED
   True
   >>> Color.RED is Color.BLUE
   False
   >>> Color.RED is not Color.BLUE
   True

列挙型の値の順序の比較はサポートされて *いません*。Enum メンバーは整数
ではありません (IntEnum を参照してください):

   >>> Color.RED < Color.BLUE
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: '<' not supported between instances of 'Color' and 'Color'

ただし等価の比較は定義されています:

   >>> Color.BLUE == Color.RED
   False
   >>> Color.BLUE != Color.RED
   True
   >>> Color.BLUE == Color.BLUE
   True

Equality comparisons against non-enumeration values will always return
"False" (again, "IntEnum" was explicitly designed to behave
differently, see below):

   >>> Color.BLUE == 2
   False

警告:

  モジュールは再読み込みすることが可能です。再読み込みされたモジュール
  に列挙型が含まれている場合、それらは再作成され、新しいメンバーは元の
  メンバーと同一でない/等しくない可能性があります。


列挙型で許されるメンバーと属性
==============================

これまでのほとんどの例では、列挙型の値に整数を使用しています。  整数を
使うのは短くて便利（そして、 関数 API ではデフォルトで設定される）です
が、これは強制されているわけではありません。大半の使用例では、列挙値の
実際の値が何であるかは意識しません。しかし、値が重要な場合、列挙型は任
意の値を持つことができます。

列挙型は Python のクラスであり、通常どおりメソッドや特殊メソッドを持つ
ことができます:

   >>> class Mood(Enum):
   ...     FUNKY = 1
   ...     HAPPY = 3
   ...
   ...     def describe(self):
   ...         # self is the member here
   ...         return self.name, self.value
   ...
   ...     def __str__(self):
   ...         return 'my custom str! {0}'.format(self.value)
   ...
   ...     @classmethod
   ...     def favorite_mood(cls):
   ...         # cls here is the enumeration
   ...         return cls.HAPPY
   ...

上記の結果が以下のようになります:

   >>> Mood.favorite_mood()
   <Mood.HAPPY: 3>
   >>> Mood.HAPPY.describe()
   ('HAPPY', 3)
   >>> str(Mood.FUNKY)
   'my custom str! 1'

The rules for what is allowed are as follows: names that start and end
with a single underscore are reserved by enum and cannot be used; all
other attributes defined within an enumeration will become members of
this enumeration, with the exception of special methods ("__str__()",
"__add__()", etc.), descriptors (methods are also descriptors), and
variable names listed in "_ignore_".

Note:  if your enumeration defines "__new__()" and/or "__init__()",
any value(s) given to the enum member will be passed into those
methods. See Planet for an example.

注釈:

  The "__new__()" method, if defined, is used during creation of the
  Enum members; it is then replaced by Enum's "__new__()" which is
  used after class creation for lookup of existing members.  See When
  to use __new__() vs. __init__() for more details.


Enumのサブクラス化の制限
========================

新しい "Enum" クラスは、ベースの enum クラスを1つ、具象データ型を1つ、
複数の "object" ベースのミックスインクラスが許容されます。これらのベー
スクラスの順序は次の通りです:

   class EnumName([mix-in, ...,] [data-type,] base-enum):
       pass

列挙型のサブクラスの作成はその列挙型にメンバーが一つも定義されていない
場合のみ行なえます。従って以下は許されません:

   >>> class MoreColor(Color):
   ...     PINK = 17
   ...
   Traceback (most recent call last):
   ...
   TypeError: <enum 'MoreColor'> cannot extend <enum 'Color'>

以下のような場合は許されます:

   >>> class Foo(Enum):
   ...     def some_behavior(self):
   ...         pass
   ...
   >>> class Bar(Foo):
   ...     HAPPY = 1
   ...     SAD = 2
   ...

メンバーが定義された列挙型のサブクラス化を許可すると、いくつかのデータ
型およびインスタンスの重要な不変条件の違反を引き起こします。とはいえ、
それが許可されると、列挙型のグループ間での共通の挙動を共有するという利
点もあります。 (OrderedEnum の例を参照してください。)


データクラスのサポート
======================

"dataclass" を継承する場合、 "__repr__()" は継承するクラス名を省略しま
す。  例えば:

   >>> from dataclasses import dataclass, field
   >>> @dataclass
   ... class CreatureDataMixin:
   ...     size: str
   ...     legs: int
   ...     tail: bool = field(repr=False, default=True)
   ...
   >>> class Creature(CreatureDataMixin, Enum):
   ...     BEETLE = 'small', 6
   ...     DOG = 'medium', 4
   ...
   >>> Creature.DOG
   <Creature.DOG: size='medium', legs=4>

標準の "repr()" を使うには、"dataclass()" の引数 "repr=False" を使用し
てください。

バージョン 3.12 で変更: dataclass のフィールドだけが値の領域に表示され
、dataclassの名前は表示されなくなりました

注釈:

  "Enum" やそのサブクラスに "dataclass()" デコレータを加えることはサポ
  ートされていません。そうしてもエラーは送出されませんが、実行時にそれ
  ぞれのメンバが互いに等しいなど、非常に奇妙な結果が起こります:

     >>> @dataclass               # don't do this: it does not make any sense
     ... class Color(Enum):
     ...    RED = 1
     ...    BLUE = 2
     ...
     >>> Color.RED is Color.BLUE
     False
     >>> Color.RED == Color.BLUE  # problem is here: they should not be equal
     True


Pickle 化
=========

列挙型は pickle 化と unpickle 化が行えます:

   >>> from test.test_enum import Fruit
   >>> from pickle import dumps, loads
   >>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
   True

通常の pickle 化の制限事項が適用されます: pickle 可能な列挙型はモジュ
ールのトップレベルで定義されていなくてはならず、unpickle 化はモジュー
ルからインポート可能でなければなりません。

注釈:

  pickle プロトコルバージョン 4 では他のクラスで入れ子になった列挙型の
  pickle 化も容易です。

It is possible to modify how enum members are pickled/unpickled by
defining "__reduce_ex__()" in the enumeration class.  The default
method is by-value, but enums with complicated values may want to use
by-name:

   >>> import enum
   >>> class MyEnum(enum.Enum):
   ...     __reduce_ex__ = enum.pickle_by_enum_name

注釈:

  フラグに名前による pickle 化を使うことは、名前の無いエイリアスが
  unpickle 化されないため推奨されません。


関数 API
========

"Enum" クラスは呼び出し可能で、以下の関数 API を提供しています:

   >>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
   >>> Animal
   <enum 'Animal'>
   >>> Animal.ANT
   <Animal.ANT: 1>
   >>> list(Animal)
   [<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>]

この API の動作は "namedtuple" と似ています。"Enum" 呼び出しの第 1 引
数は列挙型の名前です。

The second argument is the *source* of enumeration member names.  It
can be a whitespace-separated string of names, a sequence of names, a
sequence of 2-tuples with key/value pairs, or a mapping (e.g.
dictionary) of names to values.  The last two options enable assigning
arbitrary values to enumerations; the others auto-assign increasing
integers starting with 1 (use the "start" parameter to specify a
different starting value).  A new class derived from "Enum" is
returned.  In other words, the above assignment to "Animal" is
equivalent to:

   >>> class Animal(Enum):
   ...     ANT = 1
   ...     BEE = 2
   ...     CAT = 3
   ...     DOG = 4
   ...

"0" ではなく``1`` をデフォルトの開始番号とする理由は、"0" が真偽値とし
ては "False" であり、デフォルトの列挙メンバーはすべて "True" 評価され
るようにするためである。

機能 API による Enum の pickle 化は、その列挙型がどのモジュールで作成
されたかを見つけ出すためにフレームスタックの実装の詳細が使われるので、
トリッキーになることがあります (例えば別のモジュールのユーティリティ関
数を使うと失敗しますし、IronPython や Jython ではうまくいきません)。解
決策は、以下のようにモジュール名を明示的に指定することです:

   >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)

警告:

  "module" が与えられない場合、Enum はそれがなにか決定できないため、新
  しい Enum メンバーは unpickle 化できなくなります; エラーをソースの近
  いところで発生させるため、pickle 化は無効になります。

The new pickle protocol 4 also, in some circumstances, relies on
"__qualname__" being set to the location where pickle will be able to
find the class.  For example, if the class was made available in class
SomeData in the global scope:

   >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')

完全な構文は以下のようになります:

   Enum(
       value='NewEnumName',
       names=<...>,
       *,
       module='...',
       qualname='...',
       type=<mixed-in class>,
       start=1,
       )

* *value*: What the new enum class will record as its name.

* *names*: enumのメンバー。 空白またはカンマで区切られた文字列 (値は特
  に指定がない限り1から始まります):

     'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'

  または名前のイテレータで指定もできます:

     ['RED', 'GREEN', 'BLUE']

  または (名前, 値) のペアのイテレータでも指定できます:

     [('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]

  またはマッピングでも指定できます:

     {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}

* *module*: 新しい enum クラスが属するモジュールの名前です。

* *qualname*: 新しい enum クラスが属するモジュールの場所です。

* *type*: 新しい列挙型クラスにミックスインする型。

* *start*：名前だけ渡された場合にカウントを開始する番号。

バージョン 3.5 で変更: *start* 引数が追加されました。


派生列挙型
==========


IntEnum
-------

提供されている 1 つ目の "Enum" の派生型であり、 "int" のサブクラスでも
あります。 "IntEnum" のメンバーは整数と比較できます; さらに言うと、異
なる整数列挙型どうしでも比較できます:

   >>> from enum import IntEnum
   >>> class Shape(IntEnum):
   ...     CIRCLE = 1
   ...     SQUARE = 2
   ...
   >>> class Request(IntEnum):
   ...     POST = 1
   ...     GET = 2
   ...
   >>> Shape == 1
   False
   >>> Shape.CIRCLE == 1
   True
   >>> Shape.CIRCLE == Request.POST
   True

ただし、これらも標準の "Enum" 列挙型とは比較できません:

   >>> class Shape(IntEnum):
   ...     CIRCLE = 1
   ...     SQUARE = 2
   ...
   >>> class Color(Enum):
   ...     RED = 1
   ...     GREEN = 2
   ...
   >>> Shape.CIRCLE == Color.RED
   False

"IntEnum" の値は他の用途では整数のように振る舞います:

   >>> int(Shape.CIRCLE)
   1
   >>> ['a', 'b', 'c'][Shape.CIRCLE]
   'b'
   >>> [i for i in range(Shape.SQUARE)]
   [0, 1]


StrEnum
-------

提供されている2つ目の "Enum" の派生型もまた、 "str" のサブクラスでもあ
ります。"StrEnum" のメンバーは、文字列と比較できます; さらに言うと、異
なる文字列列挙型どうしでも比較できます。

Added in version 3.11.


IntFlag
-------

次の "Enum" の派生型 "IntFlag" も、"int" を基底クラスとしています。 違
いは、 "IntFlag" のメンバーをビット演算子 (&amp;, |, ^, ~) を使って組
み合わせられ、その結果も "IntFlag" メンバーになることです。 "IntEnum"
と同様、"IntFlag" のメンバーも整数であり、"int" が使用されるところであ
ればどこでも使えます。

注釈:

  "IntFlag" メンバーに対してビット演算以外のどんな演算をしても、その結
  果は "IntFlag" メンバーではなくなります。ビット単位演算の結果が
  "IntFlag" として不正な値な値の場合、値は "IntFlag" メンバーではなく
  なります。  詳しくは "FlagBoundary" を参照してください。

Added in version 3.6.

バージョン 3.11 で変更.

"IntFlag" クラスの例:

   >>> from enum import IntFlag
   >>> class Perm(IntFlag):
   ...     R = 4
   ...     W = 2
   ...     X = 1
   ...
   >>> Perm.R | Perm.W
   <Perm.R|W: 6>
   >>> Perm.R + Perm.W
   6
   >>> RW = Perm.R | Perm.W
   >>> Perm.R in RW
   True

組み合わせにも名前を付けられます:

   >>> class Perm(IntFlag):
   ...     R = 4
   ...     W = 2
   ...     X = 1
   ...     RWX = 7
   ...
   >>> Perm.RWX
   <Perm.RWX: 7>
   >>> ~Perm.RWX
   <Perm: 0>
   >>> Perm(7)
   <Perm.RWX: 7>

注釈:

  組み合わせに名前をつけたものはエイリアスとみなされます。エイリアスは
  イテレーション中には表示されませんが、値による検索では返却されます。

バージョン 3.11 で変更.

"IntFlag" と "Enum" のもう 1 つの重要な違いは、フラグが設定されていな
い (値が0である) 場合、その真偽値としての評価は "False" になることです
:

   >>> Perm.R & Perm.X
   <Perm: 0>
   >>> bool(Perm.R & Perm.X)
   False

"IntFlag" メンバーも "int" のサブクラスであるため、それらと組み合わせ
ることができます（ただし、 "IntFlag" 型ではなくなる可能性があります）:

   >>> Perm.X | 4
   <Perm.R|X: 5>

   >>> Perm.X + 8
   9

注釈:

  否定の演算子 "~" は、常に正の値を持つ "IntFlag" メンバー を返す:

     >>> (~Perm.X).value == (Perm.R|Perm.W).value == 6
     True

"IntFlag" メンバーは反復処理することもできます:

   >>> list(RW)
   [<Perm.R: 4>, <Perm.W: 2>]

Added in version 3.11.


Flag
----

最後の派生型は "Flag" です。 "IntFlag" と同様に、 "Flag" メンバーもビ
ット演算子 (&, |, ^, ~) を使って組み合わせられます。 しかし "IntFlag"
とは違い、他のどの "Flag" 列挙型とも "int" とも組み合わせたり、比較し
たりできません。 値を直接指定することも可能ですが、値として "auto" を
使い、 "Flag" に適切な値を選ばせることが推奨されています。

Added in version 3.6.

"IntFlag" と同様に、 "Flag" メンバーの組み合わせがどのフラグも設定され
ていない状態になった場合、その真偽値としての評価は "False" となります:

   >>> from enum import Flag, auto
   >>> class Color(Flag):
   ...     RED = auto()
   ...     BLUE = auto()
   ...     GREEN = auto()
   ...
   >>> Color.RED & Color.GREEN
   <Color: 0>
   >>> bool(Color.RED & Color.GREEN)
   False

個別のフラグは 2 のべき乗 (1, 2, 4, 8, ...) の値を持つべきですが、フラ
グの組み合わせはそうはなりません:

   >>> class Color(Flag):
   ...     RED = auto()
   ...     BLUE = auto()
   ...     GREEN = auto()
   ...     WHITE = RED | BLUE | GREEN
   ...
   >>> Color.WHITE
   <Color.WHITE: 7>

"フラグが設定されていない" 状態に名前を付けても、その真偽値は変わりま
せん:

   >>> class Color(Flag):
   ...     BLACK = 0
   ...     RED = auto()
   ...     BLUE = auto()
   ...     GREEN = auto()
   ...
   >>> Color.BLACK
   <Color.BLACK: 0>
   >>> bool(Color.BLACK)
   False

"Flag" メンバーは反復処理することもできます:

   >>> purple = Color.RED | Color.BLUE
   >>> list(purple)
   [<Color.RED: 1>, <Color.BLUE: 2>]

Added in version 3.11.

注釈:

  ほとんどの新しいコードでは、 "Enum" と "Flag" が強く推奨されます。
  というのは、 "IntEnum" と "IntFlag" は (整数と比較でき、従って推移的
  に他の無関係な列挙型と比較できてしまうことにより) 列挙型の意味論的な
  約束に反するからです。 "IntEnum" と "IntFlag" は、 "Enum" や "Flag"
  では上手くいかない場合のみに使うべきです; 例えば、整数定数を列挙型で
  置き換えるときや、他のシステムとの相互運用性を持たせたいときです。


その他
------

"IntEnum" は "enum" モジュールの一部ですが、単独での実装もとても簡単に
行なえます:

   class IntEnum(int, ReprEnum):   # or Enum instead of ReprEnum
       pass

This demonstrates how similar derived enumerations can be defined; for
example a "FloatEnum" that mixes in "float" instead of "int".

いくつかのルール:

1. "Enum" のサブクラスを作成するとき、複合させるデータ型は、基底クラス
   の並びで "Enum" クラス自身より先に記述しなければなりません (上記
   "IntEnum" の例を参照)。

2. 複合させる型はサブクラス化可能でなければいけません。例えば、 "bool"
   と "range" はサブクラス化できないため、複合させるとEnum作成時にエラ
   ーが発生します。

3. "Enum" のメンバーはどんなデータ型でも構いませんが、追加のデータ型 (
   例えば、上の例の "int") と複合させてしまうと、すべてのメンバーの値
   はそのデータ型でなければならなくなります。この制限は、メソッドの追
   加するだけの、他のデータ型を指定しない複合には適用されません。

4. When another data type is mixed in, the "value" attribute is *not
   the same* as the enum member itself, although it is equivalent and
   will compare equal.

5. A "data type" is a mixin that defines "__new__()", or a "dataclass"

6. %-style formatting:  "%s" and "%r" call the "Enum" class's
   "__str__()" and "__repr__()" respectively; other codes (such as
   "%i" or "%h" for IntEnum) treat the enum member as its mixed-in
   type.

7. Formatted string literals, "str.format()", and "format()" will use
   the enum's "__str__()" method.

注釈:

  Because "IntEnum", "IntFlag", and "StrEnum" are designed to be drop-
  in replacements for existing constants, their "__str__()" method has
  been reset to their data types' "__str__()" method.


When to use "__new__()" vs. "__init__()"
========================================

"__new__()" must be used whenever you want to customize the actual
value of the "Enum" member.  Any other modifications may go in either
"__new__()" or "__init__()", with "__init__()" being preferred.

例えば、複数の値をコンストラクタに渡すが、その中の1つだけを値として使
いたい場合は次のようにします:

   >>> class Coordinate(bytes, Enum):
   ...     """
   ...     Coordinate with binary codes that can be indexed by the int code.
   ...     """
   ...     def __new__(cls, value, label, unit):
   ...         obj = bytes.__new__(cls, [value])
   ...         obj._value_ = value
   ...         obj.label = label
   ...         obj.unit = unit
   ...         return obj
   ...     PX = (0, 'P.X', 'km')
   ...     PY = (1, 'P.Y', 'km')
   ...     VX = (2, 'V.X', 'km/s')
   ...     VY = (3, 'V.Y', 'km/s')
   ...

   >>> print(Coordinate['PY'])
   Coordinate.PY

   >>> print(Coordinate(3))
   Coordinate.VY

警告:

  *Do not* call "super().__new__()", as the lookup-only "__new__" is
  the one that is found; instead, use the data type directly.


細かい点
========


Supported "__dunder__" and "_sunder_" names
-------------------------------------------

The supported "__dunder__" and "_sunder_" names can be found in the
Enum API documentation.


_Private__names
---------------

Private names は列挙型メンバーには変換されず、通常の属性となります。

バージョン 3.11 で変更.


"Enum" メンバー型
-----------------

列挙型メンバーはその列挙型クラスのインスタンスであり、通常は
"EnumClass.member"  としてアクセスされます。 振る舞い メンバー しかし
、メンバー の名前と、属性/methodsが混在しているクラスとの名前の衝突を
避けるために、大文字の名前を使うことを強く推奨します。

バージョン 3.5 で変更.


Creating members that are mixed with other data types
-----------------------------------------------------

When subclassing other data types, such as "int" or "str", with an
"Enum", all values after the "=" are passed to that data type's
constructor.  For example:

   >>> class MyEnum(IntEnum):      # help(int) -> int(x, base=10) -> integer
   ...     example = '11', 16      # so x='11' and base=16
   ...
   >>> MyEnum.example.value        # and hex(11) is...
   17


"Enum" クラスとメンバーの真偽値
-------------------------------

("int", "str" などのような) 非 "Enum" 型と複合させた enum クラスは、そ
の複合された型の規則に従って評価されます; そうでない場合は、全てのメン
バーは "True" と評価されます。 メンバーの値に依存する独自の enum の真
偽値評価を行うには、クラスに次のコードを追加してください:

   def __bool__(self):
       return bool(self.value)

プレーンな "Enum" クラスは "True" として評価されます。


メソッド付きの "Enum" クラス
----------------------------

enum サブクラスに追加のメソッドを与えた場合、後述の Planet クラスのよ
うに、そのメソッドはメンバーの "dir()" に表示されますが、クラスの
"dir()" には表示されません:

   >>> dir(Planet)
   ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__']
   >>> dir(Planet.EARTH)
   ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value']


"Flag" のメンバーの組み合わせ
-----------------------------

Iterating over a combination of "Flag" members will only return the
members that are comprised of a single bit:

   >>> class Color(Flag):
   ...     RED = auto()
   ...     GREEN = auto()
   ...     BLUE = auto()
   ...     MAGENTA = RED | BLUE
   ...     YELLOW = RED | GREEN
   ...     CYAN = GREEN | BLUE
   ...
   >>> Color(3)  # named combination
   <Color.YELLOW: 3>
   >>> Color(7)      # not named combination
   <Color.RED|GREEN|BLUE: 7>


"Flag" and "IntFlag" minutia
----------------------------

例として以下のスニペットを使用します:

   >>> class Color(IntFlag):
   ...     BLACK = 0
   ...     RED = 1
   ...     GREEN = 2
   ...     BLUE = 4
   ...     PURPLE = RED | BLUE
   ...     WHITE = RED | GREEN | BLUE
   ...

the following are true:

* 単一ビットのフラグは正規形です

* 複数ビットや0ビットのフラグはエイリアスです

* 反復処理では正規形のフラグのみ返却されます:

     >>> list(Color.WHITE)
     [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>]

* negating a flag or flag set returns a new flag/flag set with the
  corresponding positive integer value:

     >>> Color.BLUE
     <Color.BLUE: 4>

     >>> ~Color.BLUE
     <Color.RED|GREEN: 3>

* 名前のないフラグについては、そのメンバーの名前から名前が生成されます
  :

     >>> (Color.RED | Color.GREEN).name
     'RED|GREEN'

     >>> class Perm(IntFlag):
     ...     R = 4
     ...     W = 2
     ...     X = 1
     ...
     >>> (Perm.R & Perm.W).name is None  # effectively Perm(0)
     True

* multi-bit flags, aka aliases, can be returned from operations:

     >>> Color.RED | Color.BLUE
     <Color.PURPLE: 5>

     >>> Color(7)  # or Color(-1)
     <Color.WHITE: 7>

     >>> Color(0)
     <Color.BLACK: 0>

* メンバーシップ/包含 のチェックでは、値が0のフラグは常に含まれるもの
  として扱われます:

     >>> Color.BLACK in Color.WHITE
     True

  それ以外では、一方のフラグの全ビットが他方のフラグに含まれる場合のみ
  、Trueが返されます:

     >>> Color.PURPLE in Color.WHITE
     True

     >>> Color.GREEN in Color.PURPLE
     False

There is a new boundary mechanism that controls how out-of-range /
invalid bits are handled: "STRICT", "CONFORM", "EJECT", and "KEEP":

* STRICT --> 無効な値が指定された場合に例外を発生させる

* CONFORM --> 無効なビットを破棄する

* EJECT --> フラグのステータスを失い、指定された値を持つ通常の int と
  なります。

* KEEP --> keep the extra bits

  * keeps Flag status and extra bits

  * extra bits do not show up in iteration

  * extra bits do show up in repr() and str()

The default for Flag is "STRICT", the default for "IntFlag" is
"EJECT", and the default for "_convert_" is "KEEP" (see "ssl.Options"
for an example of when "KEEP" is needed).


EnumとFlagはどう違うのか？
==========================

Enum は "Enum" 派生クラスやそれらのインスタンス (メンバー) 双方の多く
の側面に影響を及ぼすカスタムメタクラスを持っています。


Enum クラス
-----------

The "EnumType" metaclass is responsible for providing the
"__contains__()", "__dir__()", "__iter__()" and other methods that
allow one to do things with an "Enum" class that fail on a typical
class, such as "list(Color)" or "some_enum_var in Color".  "EnumType"
is responsible for ensuring that various other methods on the final
"Enum" class are correct (such as "__new__()", "__getnewargs__()",
"__str__()" and "__repr__()").


Flag クラス
-----------

Flags have an expanded view of aliasing: to be canonical, the value of
a flag needs to be a power-of-two value, and not a duplicate name.
So, in addition to the "Enum" definition of alias, a flag with no
value (a.k.a. "0") or with more than one power-of-two value (e.g. "3")
is considered an alias.


Enum メンバー (インスタンス)
----------------------------

The most interesting thing about enum members is that they are
singletons. "EnumType" creates them all while it is creating the enum
class itself, and then puts a custom "__new__()" in place to ensure
that no new ones are ever instantiated by returning only the existing
member instances.


Flag メンバー
-------------

フラグのメンバーは、"Flag" クラスと同様に反復処理することができ、正規
のメンバーのみが返されます。  例えば:

   >>> list(Color)
   [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>]

（"BLACK" 、 "PURPLE" 、 "WHITE" は表示されないことに注意。）

フラグのメンバーを反転させると、負の値ではなく、対応する正の値が返され
ます:

   >>> ~Color.RED
   <Color.GREEN|BLUE: 6>

フラグのメンバーは、それが含む2のべき乗の値の数に対応するlengthを持ち
ます。 例えば:

   >>> len(Color.PURPLE)
   2


Enum クックブック
=================

"Enum", "IntEnum", "StrEnum", "Flag", "IntFlag" は用途の大部分をカバー
すると予想されますが、そのすべてをカバーできているわけではありません。
ここでは、そのまま、あるいは独自の列挙型を作る例として使える、様々なタ
イプの列挙型を紹介します。


値の省略
--------

多くの用途では、列挙型の実際の値が何かは気にされません。 このタイプの
単純な列挙型を定義する方法はいくつかあります:

* 値に "auto" インスタンスを使用する

* 値として "object" インスタンスを使用する

* 値として解説文字列を使用する

* use a tuple as the value and a custom "__new__()" to replace the
  tuple with an "int" value

これらのどの方法を使ってもユーザーに対して、値は重要ではなく、他のメン
バーの番号の振り直しをする必要無しに、メンバーの追加、削除、並べ替えが
行えるということを示せます。


"auto" を使う
~~~~~~~~~~~~~

"auto" を使うと次のようになります:

   >>> class Color(Enum):
   ...     RED = auto()
   ...     BLUE = auto()
   ...     GREEN = auto()
   ...
   >>> Color.GREEN
   <Color.GREEN: 3>


"object" を使う
~~~~~~~~~~~~~~~

"object" を使うと次のようになります:

   >>> class Color(Enum):
   ...     RED = object()
   ...     GREEN = object()
   ...     BLUE = object()
   ...
   >>> Color.GREEN
   <Color.GREEN: <object object at 0x...>>

This is also a good example of why you might want to write your own
"__repr__()":

   >>> class Color(Enum):
   ...     RED = object()
   ...     GREEN = object()
   ...     BLUE = object()
   ...     def __repr__(self):
   ...         return "<%s.%s>" % (self.__class__.__name__, self._name_)
   ...
   >>> Color.GREEN
   <Color.GREEN>


解説文字列を使う
~~~~~~~~~~~~~~~~

値として文字列を使うと次のようになります:

   >>> class Color(Enum):
   ...     RED = 'stop'
   ...     GREEN = 'go'
   ...     BLUE = 'too fast!'
   ...
   >>> Color.GREEN
   <Color.GREEN: 'go'>


Using a custom "__new__()"
~~~~~~~~~~~~~~~~~~~~~~~~~~

Using an auto-numbering "__new__()" would look like:

   >>> class AutoNumber(Enum):
   ...     def __new__(cls):
   ...         value = len(cls.__members__) + 1
   ...         obj = object.__new__(cls)
   ...         obj._value_ = value
   ...         return obj
   ...
   >>> class Color(AutoNumber):
   ...     RED = ()
   ...     GREEN = ()
   ...     BLUE = ()
   ...
   >>> Color.GREEN
   <Color.GREEN: 2>

"AutoNumber" をより広い用途で使うには、シグニチャに "*args" を追加しま
す:

   >>> class AutoNumber(Enum):
   ...     def __new__(cls, *args):      # this is the only change from above
   ...         value = len(cls.__members__) + 1
   ...         obj = object.__new__(cls)
   ...         obj._value_ = value
   ...         return obj
   ...

"AutoNumber" を継承すると、追加の引数を取り扱える独自の "__init__" が
書けます。

   >>> class Swatch(AutoNumber):
   ...     def __init__(self, pantone='unknown'):
   ...         self.pantone = pantone
   ...     AUBURN = '3497'
   ...     SEA_GREEN = '1246'
   ...     BLEACHED_CORAL = () # New color, no Pantone code yet!
   ...
   >>> Swatch.SEA_GREEN
   <Swatch.SEA_GREEN: 2>
   >>> Swatch.SEA_GREEN.pantone
   '1246'
   >>> Swatch.BLEACHED_CORAL.pantone
   'unknown'

注釈:

  The "__new__()" method, if defined, is used during creation of the
  Enum members; it is then replaced by Enum's "__new__()" which is
  used after class creation for lookup of existing members.

警告:

  *Do not* call "super().__new__()", as the lookup-only "__new__" is
  the one that is found; instead, use the data type directly -- e.g.:

     obj = int.__new__(cls, value)


OrderedEnum
-----------

"IntEnum" をベースとしないため、通常の "Enum" の不変条件 (他の列挙型と
比較できないなど) のままで、メンバーを順序付けできる列挙型です:

   >>> class OrderedEnum(Enum):
   ...     def __ge__(self, other):
   ...         if self.__class__ is other.__class__:
   ...             return self.value >= other.value
   ...         return NotImplemented
   ...     def __gt__(self, other):
   ...         if self.__class__ is other.__class__:
   ...             return self.value > other.value
   ...         return NotImplemented
   ...     def __le__(self, other):
   ...         if self.__class__ is other.__class__:
   ...             return self.value <= other.value
   ...         return NotImplemented
   ...     def __lt__(self, other):
   ...         if self.__class__ is other.__class__:
   ...             return self.value < other.value
   ...         return NotImplemented
   ...
   >>> class Grade(OrderedEnum):
   ...     A = 5
   ...     B = 4
   ...     C = 3
   ...     D = 2
   ...     F = 1
   ...
   >>> Grade.C < Grade.A
   True


DuplicateFreeEnum
-----------------

値が重複するメンバーがある場合に、エイリアスを作成するのではなくエラー
を発生させます:

   >>> class DuplicateFreeEnum(Enum):
   ...     def __init__(self, *args):
   ...         cls = self.__class__
   ...         if any(self.value == e.value for e in cls):
   ...             a = self.name
   ...             e = cls(self.value).name
   ...             raise ValueError(
   ...                 "aliases not allowed in DuplicateFreeEnum:  %r --> %r"
   ...                 % (a, e))
   ...
   >>> class Color(DuplicateFreeEnum):
   ...     RED = 1
   ...     GREEN = 2
   ...     BLUE = 3
   ...     GRENE = 2
   ...
   Traceback (most recent call last):
     ...
   ValueError: aliases not allowed in DuplicateFreeEnum:  'GRENE' --> 'GREEN'

注釈:

  これは Enum に別名を無効にするのと同様な振る舞いの追加や変更をおこな
  うためのサブクラス化に役立つ例です。単に別名を無効にしたいだけなら、
  "unique()" デコレーターを使用して行えます。


MultiValueEnum
--------------

Supports having more than one value per member:

   >>> class MultiValueEnum(Enum):
   ...     def __new__(cls, value, *values):
   ...         self = object.__new__(cls)
   ...         self._value_ = value
   ...         for v in values:
   ...             self._add_value_alias_(v)
   ...         return self
   ...
   >>> class DType(MultiValueEnum):
   ...     float32 = 'f', 8
   ...     double64 = 'd', 9
   ...
   >>> DType('f')
   <DType.float32: 'f'>
   >>> DType(9)
   <DType.double64: 'd'>


Planet
------

If "__new__()" or "__init__()" is defined, the value of the enum
member will be passed to those methods:

   >>> class Planet(Enum):
   ...     MERCURY = (3.303e+23, 2.4397e6)
   ...     VENUS   = (4.869e+24, 6.0518e6)
   ...     EARTH   = (5.976e+24, 6.37814e6)
   ...     MARS    = (6.421e+23, 3.3972e6)
   ...     JUPITER = (1.9e+27,   7.1492e7)
   ...     SATURN  = (5.688e+26, 6.0268e7)
   ...     URANUS  = (8.686e+25, 2.5559e7)
   ...     NEPTUNE = (1.024e+26, 2.4746e7)
   ...     def __init__(self, mass, radius):
   ...         self.mass = mass       # in kilograms
   ...         self.radius = radius   # in meters
   ...     @property
   ...     def surface_gravity(self):
   ...         # universal gravitational constant  (m3 kg-1 s-2)
   ...         G = 6.67300E-11
   ...         return G * self.mass / (self.radius * self.radius)
   ...
   >>> Planet.EARTH.value
   (5.976e+24, 6378140.0)
   >>> Planet.EARTH.surface_gravity
   9.802652743337129


TimePeriod
----------

An example to show the "_ignore_" attribute in use:

   >>> import datetime as dt
   >>> class Period(dt.timedelta, Enum):
   ...     "different lengths of time"
   ...     _ignore_ = 'Period i'
   ...     Period = vars()
   ...     for i in range(367):
   ...         Period['day_%d' % i] = i
   ...
   >>> list(Period)[:2]
   [<Period.day_0: datetime.timedelta(0)>, <Period.day_1: datetime.timedelta(days=1)>]
   >>> list(Period)[-2:]
   [<Period.day_365: datetime.timedelta(days=365)>, <Period.day_366: datetime.timedelta(days=366)>]


EnumType のサブクラスを作る
===========================

While most enum needs can be met by customizing "Enum" subclasses,
either with class decorators or custom functions, "EnumType" can be
subclassed to provide a different Enum experience.
