列舉類定義和使用
一些具有特殊含義的類,其例項化物件的個數往往是固定的,比如用一個類表示月份,則該類的例項物件最多有 12 個;再比如用一個類表示季節,則該類的例項化物件最多有 4 個。
針對這種特殊的類,Python3.4 中新增加了 Enum 列舉類。也就是說,對於這些例項化物件個數固定的類,可以用列舉類來定義。
例如,下面程式演示瞭如何定義一個列舉類:
from enum import Enum class Color(Enum): # 為序列值指定value值 red = 1 green = 2 blue = 3
如果想將一個類定義為列舉類,只需要令其繼承自 enum 模組中的 Enum 類即可。例如在上面程式中,Color 類繼承自 Enum 類,則證明這是一個列舉類。
在 Color 列舉類中,red、green、blue 都是該類的成員(可以理解為是類變數)。注意,列舉類的每個成員都由 2 部分組成,分別為 name 和 value,其中 name 屬性值為該列舉值的變數名(如 red),value代表該列舉值的序號(序號通常從 1 開始)。
和普通類的用法不同,列舉類不能用來例項化物件,但這並不妨礙我們訪問列舉類中的成員。訪問列舉類成員的方式有多種,例如以 Color 列舉類為例,在其基礎上新增如下程式碼:
#呼叫列舉成員的 3 種方式 print(Color.red) print(Color['red']) print(Color(1)) #調取列舉成員中的 value 和 name print(Color.red.value) print(Color.red.name) #遍歷列舉類中所有成員的 2 種方式 for color in Color: print(color)
程式輸出結果為:
Color.red
Color.red
Color.red
1
red
Color.red
Color.green
Color.blue
列舉類成員之間不能比較打下,但可以用 == 或者 is 進行比較是否相等,例如:
print(Color.red == Color.green) print(Color.red.name is Color.green.name)
輸出結果為:
Flase
Flase
需要注意的是,列舉類中各個成員的值,不能在類的外部做任何修改,也就是說,下面語法的做法是錯誤的:
- Color.red = 4
除此之外,該列舉類還提供了一個 __members__ 屬性,該屬性是一個包含列舉類中所有成員的字典,通過遍歷該屬性,也可以訪問列舉類中的各個成員。例如:
for name,member in Color.__members__.items(): print(name,"->",member)
輸出結果為:
red -> Color.red
green -> Color.green
blue -> Color.blue
值得一提的是,Python 列舉類中各個成員必須保證 name 互不相同,但 value 可以相同,舉個例子:
from enum import Enum class Color(Enum): # 為序列值指定value值 red = 1 green = 1 blue = 3 print(Color['green'])
輸出結果為:
Color.red
可以看到,Color 列舉類中 red 和 green 具有相同的值(都是 1),Python 允許這種情況的發生,它會將 green 當做是 red 的別名,因此當訪問 green 成員時,最終輸出的是 red。
在實際程式設計過程中,如果想避免發生這種情況,可以藉助@unique 裝飾器,這樣當列舉類中出現相同值的成員時,程式會報 ValueError 錯誤。例如:
#引入 unique from enum import Enum,unique #新增 unique 裝飾器 @unique class Color(Enum): # 為序列值指定value值 red = 1 green = 1 blue = 3 print(Color['green'])
執行程式會報錯:
Traceback (most recent call last):
File "D:\python3.6\demo.py", line 3, in <module>
class Color(Enum):
File "D:\python3.6\lib\enum.py", line 834, in unique
(enumeration, alias_details))
ValueError: duplicate values found in <enum 'Color'>: green -> red
除了通過繼承 Enum 類的方法建立列舉類,還可以使用 Enum() 函式建立列舉類。例如:
from enum import Enum #建立一個列舉類 Color = Enum("Color",('red','green','blue')) #呼叫列舉成員的 3 種方式 print(Color.red) print(Color['red']) print(Color(1)) #調取列舉成員中的 value 和 name print(Color.red.value) print(Color.red.name) #遍歷列舉類中所有成員的 2 種方式 for color in Color: print(color)
Enum() 函式可接受 2 個引數,第一個用於指定列舉類的類名,第二個引數用於指定列舉類中的多個成員。
如上所示,僅通過一行程式碼,即建立了一個和前面的 Color 類相同的列舉類。執行程式,其輸出結果為:
Color.red
Color.red
Color.red
1
red
Color.red
Color.green
Color.blue