enum --- 對列舉的支援

在 3.4 版被加入.

原始碼:Lib/enum.py

Important

本頁包含 API 的參考資訊。關於教學資訊及更多進階主題的討論請參考


列舉:

  • 是一組綁定唯一值的代表名稱(成員)

  • 可以用疊代的方式以定義的順序回傳其正式 (canonical)(即非別名)成員

  • 使用call 語法來透過值回傳成員

  • 使用index 語法來透過名稱回傳成員

列舉透過class 語法或函式呼叫的語法來建立:

>>>fromenumimportEnum>>># class 語法>>>classColor(Enum):...RED=1...GREEN=2...BLUE=3>>># 函式語法>>>Color=Enum('Color',[('RED',1),('GREEN',2),('BLUE',3)])

雖然我們可以用class 語法來建立列舉,列舉並不是標準的 Python 類別。參考列舉有何差異以取得更多細節。

備註

命名方式

  • Color 類別是一個列舉(或enum

  • Color.REDColor.GREEN 等屬性是列舉成員(或成員),並且使用上可以看作常數。

  • 列舉成員有名稱Color.RED 的名稱是REDColor.BLUE 的值是3 諸如此類)


模組內容

EnumType

Enum 及其子類別的type

Enum

用來建立列舉常數的基礎類別。

IntEnum

用來建立列舉常數的基礎類別,同時也是int 的子類別。(備註

StrEnum

用來建立列舉常數的基礎類別,同時也是str 的子類別。(備註

Flag

用來建立列舉常數的基礎類別,可以使用位元操作來結合成員且其結果不失去Flag 的成員資格。

IntFlag

用來建立列舉常數的基礎類別,可以使用位元操作來結合成員且其結果不失去IntFlag 的成員資格。IntFlag 的成員也是int 的子類別。(備註

ReprEnum

IntEnumStrEnumIntFlag 所使用來保留這些混合型別的str()

EnumCheck

一個有CONTINUOUSNAMED_FLAGSUNIQUE 這些值的列舉,和verify() 一起使用來確保給定的列舉符合多種限制。

FlagBoundary

一個有STRICTCONFORMEJECTKEEP 這些值的列舉,允許列舉對如何處理非法值做更細微的控制。

EnumDict

dict 的子類別,用於當作EnumType 的子類別時使用。

auto

列舉成員的實例會被取代成合適的值。StrEnum 預設是小寫版本的成員名稱,其它列舉則預設是 1 且往後遞增。

property()

允許Enum 成員擁有屬性且不會與成員名稱有衝突。valuename 屬性是用這個方式來實作。

unique()

Enum 類別的裝飾器,用來確保任何值只有綁定到一個名稱上。

verify()

Enum 類別的裝飾器,用來檢查列舉上使用者所選的限制。

member()

obj 變成成員。可以當作裝飾器使用。

nonmember()

不讓obj 變成成員。可以當作裝飾器使用。

global_enum()

修改列舉上的str()repr() ,讓成員顯示為屬於模組而不是類別,並將該列舉成員匯出到全域命名空間。

show_flag_values()

回傳旗標 (flag) 裡包含的所有 2 的次方的整數串列。

在 3.6 版被加入:Flag,IntFlag,auto

在 3.11 版被加入:StrEnum,EnumCheck,ReprEnum,FlagBoundary,property,member,nonmember,global_enum,show_flag_values

在 3.13 版被加入:EnumDict


資料型別

classenum.EnumType

EnumTypeenum 列舉的metaclassEnumType 可以有子類別 -- 細節請參考建立 EnumType 的子類別

EnumType 負責在最後的列舉上面設定正確的__repr__()__str__()__format__()__reduce__() 方法,以及建立列舉成員、正確處理重複、提供列舉類別的疊代等等。

__call__(cls,value,names=None,*,module=None,qualname=None,type=None,start=1,boundary=None)

這個方法可以用兩種不同的方式呼叫:

  • 查詢已存在的成員:

    cls:

    所呼叫的列舉類別。

    value:

    要查詢的值。

  • 使用cls 列舉來建立新列舉(只有在現有列舉沒有任何成員時)

    cls:

    所呼叫的列舉類別。

    value:

    要建立的新列舉的名稱。

    names:

    新列舉的成員的名稱/值。

    module:

    新列舉要建立在哪個模組名稱下。

    qualname:

    這個列舉在模組裡實際上的位置。

    type:

    新列舉的混合型別。

    start:

    列舉的第一個整數值(由auto 所使用)

    boundary:

    在位元操作時怎麼處理範圍外的值(只有Flag 會用到)

__contains__(cls,member)

如果 member 屬於cls 則回傳True

>>>some_var=Color.RED>>>some_varinColorTrue>>>Color.RED.valueinColorTrue

在 3.12 版的變更:在 Python 3.12 之前,如果用非列舉成員做屬於檢查 (containment check) 會引發TypeError

__dir__(cls)

回傳['__class__','__doc__','__members__','__module__']cls 的成員名稱:

>>>dir(Color)['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__']
__getitem__(cls,name)

回傳cls 中符合name 的列舉成員,或引發KeyError

>>>Color['BLUE']<Color.BLUE: 3>
__iter__(cls)

以定義的順序回傳在cls 中的每個成員:

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

回傳cls 的成員數量:

>>>len(Color)3
__members__

回傳每個列舉名稱到其成員的對映,包括別名

__reversed__(cls)

以跟定義相反的順序回傳cls 的每個成員:

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

新增一個名稱作為現有成員的別名。如果該名稱已被指派給不同的成員,則會引發NameError

_add_value_alias_()

新增一個值作為現有成員的別名。如果該值已與不同成員連結,則會引發ValueError

在 3.11 版被加入:在 3.11 之前,EnumType 稱作EnumMeta,其目前仍可作為別名使用。

classenum.Enum

Enum 是所有enum 列舉的基礎類別。

name

用來定義Enum 成員的名稱:

>>>Color.BLUE.name'BLUE'
value

Enum 成員給定的值:

>>>Color.RED.value1

成員的值,可以在__new__() 設定。

備註

列舉成員的值

成員的值可以是任何值:intstr 等等。如果實際使用什麼值並不重要,你可以使用auto 實例,它會為你選擇合適的值。更多細節請參考auto

雖然可以使用可變的 (mutable) / 不可雜湊的 (unhashable) 值,例如dictlist 或可變的dataclass,它們在建立期間會對效能產生相對於列舉中可變的 / 不可雜湊的值總數量的二次方影響。

_name_

成員名稱。

_value_

成員的值,可以在__new__() 設定。

_order_

已不再使用,只為了向後相容而保留(類別屬性,在類別建立時移除)

_ignore_

_ignore_ 只有在建立的時候用到,在列舉建立完成後會被移除。

_ignore_ 是一個不會變成成員的名稱串列,在列舉建立完成後其名稱會被移除。範例請參考TimePeriod

__dir__(self)

回傳['__class__','__doc__','__module__','name','value'] 及任何self.__class__ 上定義的公開方法:

>>>fromdatetimeimportdate>>>classWeekday(Enum):...MONDAY=1...TUESDAY=2...WEDNESDAY=3...THURSDAY=4...FRIDAY=5...SATURDAY=6...SUNDAY=7...@classmethod...deftoday(cls):...print('today is%s'%cls(date.today().isoweekday()).name)...>>>dir(Weekday.SATURDAY)['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value']
_generate_next_value_(name,start,count,last_values)
name:

定義的成員名稱(例如 'RED')。

start:

列舉的開始值,預設為 1。

count:

已定義的成員數量,不包含目前這一個。

last_values:

一個之前值的串列。

一個staticmethod,用來決定auto 下一個要回傳的值的:

>>>fromenumimportauto>>>classPowersOfThree(Enum):...@staticmethod...def_generate_next_value_(name,start,count,last_values):...return3**(count+1)...FIRST=auto()...SECOND=auto()...>>>PowersOfThree.SECOND.value9
__init__(self,*args,**kwds)

預設情況下,不執行任何操作。如果在成員賦值中給出多個值,這些值將成為與__init__ 分別的引數;例如

>>>fromenumimportEnum>>>classWeekday(Enum):...MONDAY=1,'Mon'

Weekday.__init__() 將被稱為Weekday.__init__(self,1,'Mon')

__init_subclass__(cls,**kwds)

一個classmethod,用來進一步設定後續的子類別,預設不做任何事。

_missing_(cls,value)

一個classmethod,用來查詢在cls 裡找不到的值。預設不做任何事,但可以被覆寫以實作客製化的搜尋行為:

>>>fromenumimportStrEnum>>>classBuild(StrEnum):...DEBUG=auto()...OPTIMIZED=auto()...@classmethod...def_missing_(cls,value):...value=value.lower()...formemberincls:...ifmember.value==value:...returnmember...returnNone...>>>Build.DEBUG.value'debug'>>>Build('deBUG')<Build.DEBUG: 'debug'>
__new__(cls,*args,**kwds)

預設情況下不存在。如果有指定,無論是在列舉類別定義中還是在 mixin 類別中(例如int),都將傳遞成員賦值中給出的所有值;例如

>>>fromenumimportEnum>>>classMyIntEnum(int,Enum):...TWENTYSIX='1a',16

會產生呼叫int('1a',16) 而該成員的值為26

備註

當寫自訂的__new__ 時,不要使用super().__new__,而是要呼叫適當的__new__

__repr__(self)

回傳呼叫repr() 時使用的字串。預設回傳Enum 名稱、成員名稱及值,但可以被覆寫:

>>>classOtherStyle(Enum):...ALTERNATE=auto()...OTHER=auto()...SOMETHING_ELSE=auto()...def__repr__(self):...cls_name=self.__class__.__name__...returnf'{cls_name}.{self.name}'...>>>OtherStyle.ALTERNATE,str(OtherStyle.ALTERNATE),f"{OtherStyle.ALTERNATE}"(OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE')
__str__(self)

回傳呼叫str() 時使用的字串。預設回傳Enum 名稱及成員名稱,但可以被覆寫:

>>>classOtherStyle(Enum):...ALTERNATE=auto()...OTHER=auto()...SOMETHING_ELSE=auto()...def__str__(self):...returnf'{self.name}'...>>>OtherStyle.ALTERNATE,str(OtherStyle.ALTERNATE),f"{OtherStyle.ALTERNATE}"(<OtherStyle.ALTERNATE: 1>, 'ALTERNATE', 'ALTERNATE')
__format__(self)

回傳呼叫format()f-string 時使用的字串。預設回傳__str__() 的回傳值,但可以被覆寫:

>>>classOtherStyle(Enum):...ALTERNATE=auto()...OTHER=auto()...SOMETHING_ELSE=auto()...def__format__(self,spec):...returnf'{self.name}'...>>>OtherStyle.ALTERNATE,str(OtherStyle.ALTERNATE),f"{OtherStyle.ALTERNATE}"(<OtherStyle.ALTERNATE: 1>, 'OtherStyle.ALTERNATE', 'ALTERNATE')

備註

Enum 使用auto 會產生從1 開始遞增的整數。

在 3.12 版的變更:新增Dataclass support

classenum.IntEnum

IntEnumEnum 一樣,但其成員同時也是整數而可以被用在任何使用整數的地方。如果IntEnum 成員經過任何整數運算,結果值會失去其列舉狀態。

>>>fromenumimportIntEnum>>>classNumber(IntEnum):...ONE=1...TWO=2...THREE=3...>>>Number.THREE<Number.THREE: 3>>>>Number.ONE+Number.TWO3>>>Number.THREE+58>>>Number.THREE==3True

備註

IntEnum 使用auto 會產生從1 開始遞增的整數。

在 3.11 版的變更:為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,__str__() 現在會是int.__str__()。為了同樣的理由,__format__() 已經是int.__format__()

classenum.StrEnum

StrEnumEnum 一樣,但其成員同時也是字串而可以被用在幾乎所有使用字串的地方。StrEnum 成員經過任何字串操作的結果會不再是列舉的一部份。

備註

stdlib 裡有些地方會檢查只能是str 而不是str 的子類別(也就是type(unknown)==str 而不是isinstance(unknown,str)),在這些地方你需要使用str(StrEnum.member)

備註

StrEnum 使用auto 會產生小寫的成員名稱當作值。

備註

為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,__str__() 現在會是str.__str__()。為了同樣的理由,__format__() 也會是str.__format__()

在 3.11 版被加入.

classenum.Flag

FlagEnum 相同,但其成員支援位元運算子& (AND)、| (OR)、^ (XOR) 和~ (INVERT);這些操作的結果是列舉的成員(的別名)。

__contains__(self,value)

如果 value 在 self 裡則回傳True

>>>fromenumimportFlag,auto>>>classColor(Flag):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>purple=Color.RED|Color.BLUE>>>white=Color.RED|Color.GREEN|Color.BLUE>>>Color.GREENinpurpleFalse>>>Color.GREENinwhiteTrue>>>purpleinwhiteTrue>>>whiteinpurpleFalse
__iter__(self):

回傳所有包含的非別名成員:

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

在 3.11 版被加入.

__len__(self):

回傳旗標裡的成員數量:

>>>len(Color.GREEN)1>>>len(white)3

在 3.11 版被加入.

__bool__(self):

如果成員在旗標裡則回傳True,否則回傳False

>>>bool(Color.GREEN)True>>>bool(white)True>>>black=Color(0)>>>bool(black)False
__or__(self,other)

回傳和 other 做 OR 過後的二進位旗標:

>>>Color.RED|Color.GREEN<Color.RED|GREEN: 3>
__and__(self,other)

回傳和 other 做 AND 過後的二進位旗標:

>>>purple&white<Color.RED|BLUE: 5>>>>purple&Color.GREEN<Color: 0>
__xor__(self,other)

回傳和 other 做 XOR 過後的二進位旗標:

>>>purple^white<Color.GREEN: 2>>>>purple^Color.GREEN<Color.RED|GREEN|BLUE: 7>
__invert__(self):

回傳所有在type(self) 但不在self 裡的旗標:

>>>~white<Color: 0>>>>~purple<Color.GREEN: 2>>>>~Color.RED<Color.GREEN|BLUE: 6>
_numeric_repr_()

用來格式化任何剩下未命名數值的函式。預設是值的 repr,常見選擇是hex()oct()

備註

Flag 使用auto 會產生從1 開始 2 的次方的整數。

在 3.11 版的變更:值為 0 的旗標的repr() 已改變。現在是:

>>>Color(0)<Color: 0>
classenum.IntFlag

IntFlagFlag 一樣,但其成員同時也是整數而可以被用在任何使用整數的地方。

>>>fromenumimportIntFlag,auto>>>classColor(IntFlag):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>Color.RED&2<Color: 0>>>>Color.RED|2<Color.RED|GREEN: 3>

如果IntFlag 成員經過任何整數運算,其結果不是IntFlag

>>>Color.RED+23

如果IntFlag 成員經過Flag 操作且:

  • 結果是合法的IntFlag:回傳IntFlag

  • 結果不是合法的IntFlag:結果會根據FlagBoundary 的設定

未命名且值為 0 的旗標的repr() 已改變。現在是:

>>>Color(0)<Color: 0>

備註

IntFlag 使用auto 會產生從1 開始 2 的次方的整數。

在 3.11 版的變更:為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,__str__() 現在會是int.__str__()。為了同樣的理由,__format__() 已經是int.__format__()

IntFlag 的反轉 (inversion) 現在會回傳正值,該值是不在給定旗標的所有旗標聯集,而不是一個負值。這符合現有Flag 的行為。

classenum.ReprEnum

ReprEnum 使用Enumrepr(),但使用混合資料型別的str()

繼承ReprEnum 來保留混合資料型別的str() /format(),而不是使用Enum 預設的str()

在 3.11 版被加入.

classenum.EnumCheck

EnumCheck 包含verify() 裝飾器使用的選項,以確保多樣的限制,不符合限制會產生ValueError

UNIQUE

確保每個值只有一個名稱:

>>>fromenumimportEnum,verify,UNIQUE>>>@verify(UNIQUE)...classColor(Enum):...RED=1...GREEN=2...BLUE=3...CRIMSON=1Traceback (most recent call last):...ValueError:aliases found in <enum 'Color'>: CRIMSON -> RED
CONTINUOUS

確保在最小值成員跟最大值成員間沒有缺少值:

>>>fromenumimportEnum,verify,CONTINUOUS>>>@verify(CONTINUOUS)...classColor(Enum):...RED=1...GREEN=2...BLUE=5Traceback (most recent call last):...ValueError:invalid enum 'Color': missing values 3, 4
NAMED_FLAGS

確保任何旗標群組 / 遮罩只包含命名旗標 -- 當值是用指定而不是透過auto() 產生時是很實用的:

>>>fromenumimportFlag,verify,NAMED_FLAGS>>>@verify(NAMED_FLAGS)...classColor(Flag):...RED=1...GREEN=2...BLUE=4...WHITE=15...NEON=31Traceback (most recent call last):...ValueError:invalid Flag 'Color': aliases WHITE and NEON are missing combined values of 0x18 [use enum.show_flag_values(value) for details]

備註

CONTINUOUS 和 NAMED_FLAGS 是設計用來運作在整數值的成員上。

在 3.11 版被加入.

classenum.FlagBoundary

FlagBoundary 控制在Flag 及其子類別中如何處理範圍外的值。

STRICT

範圍外的值會引發ValueError。這是Flag 的預設行為:

>>>fromenumimportFlag,STRICT,auto>>>classStrictFlag(Flag,boundary=STRICT):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>StrictFlag(2**2+2**4)Traceback (most recent call last):...ValueError:<flag 'StrictFlag'> invalid value 20    given 0b0 10100  allowed 0b0 00111
CONFORM

會移除範圍外的值中的非法值,留下合法的Flag 值:

>>>fromenumimportFlag,CONFORM,auto>>>classConformFlag(Flag,boundary=CONFORM):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>ConformFlag(2**2+2**4)<ConformFlag.BLUE: 4>
EJECT

範圍外的值會失去它們的Flag 成員資格且恢復成int

>>>fromenumimportFlag,EJECT,auto>>>classEjectFlag(Flag,boundary=EJECT):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>EjectFlag(2**2+2**4)20
KEEP

範圍外的值會被保留,Flag 成員資格也會被保留。這是IntFlag 的預設行為:

>>>fromenumimportFlag,KEEP,auto>>>classKeepFlag(Flag,boundary=KEEP):...RED=auto()...GREEN=auto()...BLUE=auto()...>>>KeepFlag(2**2+2**4)<KeepFlag.BLUE|16: 20>

在 3.11 版被加入.

classenum.EnumDict

EnumDictdict 的子類別,用來作為定義列舉類別的命名空間(參見Preparing the class namespace)。它被公開來使得EnumType 的子類別能具有進階行為,例如讓每個成員有多個值。它應該在被呼叫時帶上正在建立的列舉類別名稱,否則私有名稱和內部類別將無法被正確處理。

注意只有MutableMapping 介面(__setitem__()update())被覆寫。可能可以使用其他dict 操作來繞過檢查,例如|=

member_names

一個成員名稱的串列。

在 3.13 版被加入.


支援的__dunder__ 名稱

__members__ 是一個唯讀有序的成員名稱成員項目的對映。只有在類別上可用。

__new__(),如果有指定,它必須建立並回傳列舉成員;適當地設定成員的_value_ 也是一個很好的主意。一旦所有成員都建立之後就不會再被用到。

支援的_sunder_ 名稱

  • _add_alias_() -- 新增一個名稱作為現有成員的別名。

  • _add_value_alias_() -- 新增一個值作為現有成員的別名。

  • _name_ -- 成員名稱

  • _value_ -- 成員的值;可以在__new__ 設定

  • _missing_() -- 當值沒有被找到時會使用的查詢函式;可以被覆寫

  • _ignore_ -- 一個名稱的串列,可以是liststr,它不會被轉換成成員,且在最後的類別上會被移除

  • _order_ -- 不再被使用,僅為了向後相容而保留(類別屬性,在類別建立時移除)

  • _generate_next_value_() -- 用來為列舉成員取得合適的值;可以被覆寫

    備註

    對標準的Enum 類別來說,下一個被選擇的值是所看過的最大值加一。

    Flag 類別來說,下一個被選擇的值是下一個最大的 2 的次方的數字。

  • 雖然_sunder_ 名稱通常保留用於Enum 類別的進一步開發而不能被使用,但有些是明確允許的:

在 3.6 版被加入:_missing__order__generate_next_value_

在 3.7 版被加入:_ignore_

在 3.13 版被加入:_add_alias__add_value_alias__repr_*


通用項目與裝飾器

classenum.auto

auto 可以用來取代給值。如果使用的話,Enum 系統會呼叫Enum_generate_next_value_() 來取得合適的值。對EnumIntEnum 來說,合適的值是最後一個值加一;對FlagIntFlag 來說,是第一個比最大值還大的 2 的次方的數字;對StrEnum 來說,是成員名稱的小寫版本。如果混用auto() 和手動指定值的話要特別注意。

auto 實例只有在最上層的賦值時才會被解析:

  • FIRST=auto() 可以運作(auto() 會被取代成1

  • SECOND=auto(),-2 可以運作(auto 會被取代成2, 因此2,-2 會被用來建立列舉成員SECOND

  • THREE=[auto(),-3]無法運作(<auto實例>,-3 會被用來建立列舉成員THREE

在 3.11.1 版的變更:在之前的版本中,auto() 必須是賦值行裡的唯一內容才能運作正確。

可以覆寫_generate_next_value_ 來客製auto 使用的值。

備註

在 3.13 預設_generate_next_value_ 總是回傳最大的成員值加一,如果任何成員是不相容的型別就會失敗。

@enum.property

和內建的property 相似的裝飾器,但只專門針對列舉。它允許成員屬性和成員本身有相同名稱。

備註

屬性和成員必須定義在分開的類別裡;例如valuename 屬性定義在Enum 類別而Enum 子類別可以定義成員名稱為valuename

在 3.11 版被加入.

@enum.unique

專門針對列舉的class 裝飾器。它搜尋列舉的__members__,蒐集任何它找到的別名;如果有找到任何別名則引發ValueError 並附上細節:

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

專門針對列舉的class 裝飾器。使用EnumCheck 裡的成員來指定在裝飾的列舉上應該檢查什麼限制。

在 3.11 版被加入.

@enum.member

列舉所使用的裝飾器:其目標會變成成員。

在 3.11 版被加入.

@enum.nonmember

列舉所使用的裝飾器:其目標不會變成成員。

在 3.11 版被加入.

@enum.global_enum

修改列舉的str()repr() 的裝飾器,讓成員顯示為屬於模組而不是其類別。應該只有當列舉成員被匯出到模組的全域命名空間才使用(範例請參考re.RegexFlag)。

在 3.11 版被加入.

enum.show_flag_values(value)

回傳在旗標中包含的所有 2 的次方的整數串列。

在 3.11 版被加入.


備註

IntEnumStrEnumIntFlag

這三種列舉型別是設計來直接取代現有以整數及字串為基底的值;因此它們有額外的限制:

  • __str__ 使用值而不是列舉成員的名稱

  • __format__ 因為使用__str__,也會使用值而不是列舉成員的名稱

如果你不需要或不想要這些限制,你可以透過混合intstr 型別來建立自己的基礎類別:

>>>fromenumimportEnum>>>classMyIntEnum(int,Enum):...pass

或者你也可以在你的列舉重新給定合適的str()

>>>fromenumimportEnum,IntEnum>>>classMyIntEnum(IntEnum):...__str__=Enum.__str__