Python 的枚舉類型

起步

Python 的原生類型中並不包含枚舉類型。爲了提供更好的解決方案,Python 經過 PEP 435 在 3.4 版本中添加了 enum 標準庫。python

枚舉類型能夠看做是一種標籤或是一系列常量的集合,一般用於表示某些特定的有限集合,例如星期、月份、狀態等。在沒有專門提供枚舉類型的時候咱們是怎麼作呢,通常就經過字典或類來實現:post

Color = {
    'RED'  : 1,
    'GREEN': 2,
    'BLUE' : 3,
}

class Color:
    RED   = 1
    GREEN = 2
    BLUE  = 3

這種來實現枚舉若是當心翼翼地使用固然沒什麼問題,畢竟是一種妥協的解決方案。它的隱患在於能夠被修改。學習

使用 Enum

更好的方式是使用標準庫提供的 Enum 類型,官方庫值得信賴。3.4 以前的版本也能夠經過 pip install enum 下載支持的庫。簡單的示例:code

from enum import Enum
class Color(Enum):
    red = 1
    green = 2
    blue = 3

枚舉成員有值(默承認重複),枚舉成員具備友好的字符串表示:ip

>>> print(Color.red)
Color.red
>>> print(repr(Color.red))
<Color.red: 1>
>>> type(Color.red)
<Enum 'Color'>
>>> isinstance(Color.green, Color)
True

枚舉類型不可實例化,不可更改。ci

定義枚舉

定義枚舉時,成員名不容許重複字符串

class Color(Enum):
    red = 1
    green = 2
    red = 3    # TypeError: Attempted to reuse key: 'red'

成員值容許相同,第二個成員的名稱被視做第一個成員的別名 get

class Color(Enum):
    red   = 1
    green = 2
    blue  = 1

print(Color.red)              # Color.red
print(Color.blue)             # Color.red
print(Color.red is Color.blue)# True
print(Color(1))               # Color.red  在經過值獲取枚舉成員時,只能獲取到第一個成員

若要不能定義相同的成員值,能夠經過 unique 裝飾 源碼

from enum import Enum, unique
@unique
class Color(Enum):
    red   = 1
    green = 2
    blue  = 1  # ValueError: duplicate values found in <enum 'Color'>: blue -> red

枚舉取值

能夠經過成員名來獲取成員也能夠經過成員值來獲取成員:it

print(Color['red'])  # Color.red  經過成員名來獲取成員

print(Color(1))      # Color.red  經過成員值來獲取成員

每一個成員都有名稱屬性和值屬性:

member = Color.red
print(member.name)   # red
print(member.value)  # 1

支持迭代的方式遍歷成員,按定義的順序,若是有值重複的成員,只獲取重複的第一個成員:

for color in Color:
    print(color)

特殊屬性 __members__ 是一個將名稱映射到成員的有序字典,也能夠經過它來完成遍歷:

for color in Color.__members__.items():
    print(color)          # ('red', <Color.red: 1>)

枚舉比較

枚舉的成員能夠經過 is 同一性比較或經過 == 等值比較:

Color.red is Color.red
Color.red is not Color.blue

Color.blue == Color.red
Color.blue != Color.red

枚舉成員不能進行大小比較:

Color.red < Color.blue    # TypeError: unorderable types: Color() < Color()

擴展枚舉 IntEnum

IntEnumEnum 的擴展,不一樣類型的整數枚舉也能夠相互比較:

from enum import IntEnum
class Shape(IntEnum):
    circle = 1
    square = 2

class Request(IntEnum):
    post = 1
    get = 2

print(Shape.circle == 1)            # True
print(Shape.circle < 3)             # True
print(Shape.circle == Request.post) # True
print(Shape.circle >= Request.post) # True

總結

enum 模塊功能很明確,用法也簡單,其實現的方式也值得學習,有機會的話能夠看看它的源碼。

相關文章
相關標籤/搜索