介紹
enum是一個用來枚舉的模塊
創建枚舉類型
import enum
# 創建一個類,繼承自enum下的Enum
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = 6
# 下面便可以通過名稱直接獲取成員
print(Color["red"], type(Color["red"])) # Color.red <enum 'Color'>
print(Color.red, type(Color.red)) # Color.red <enum 'Color'>
# 打印的是<enum 'Color'>類型
# 那么如何獲取里面的值呢?
# 調用name獲取名稱,調用value獲取值
print(Color.red.name, type(Color.red.name)) # red <class 'str'>
print(Color.red.value) # 1
# 也可以通過迭代來獲取值
for c in Color:
print(c.name, c.value)
"""
red 1
green 2
blue 3
yellow 4
pink 5
cyan 6
"""
名稱或者值相同
import enum
# 如果我定義了重復的key(仮)
try:
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = 6
cyan = 5
except Exception as e:
print(e) # Attempted to reuse key: 'cyan'
# 提示我們key重復了
import enum
# 如果我定義了重復的value(仮)
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = 6
purple = 6
# 這是通過value來獲取成員
# 獲取成員可以通過Color.key | Color[key]的方式,還可以使用Color(value)的方式
print(Color(6).name) # cyan
print(Color.purple.name) # cyan
# 可以看到只打印了cyan
# 如果值相同的話,那么后者相當於前者的別名,兩者指向的內容是一樣的
for c in Color:
print(c)
"""
Color.red
Color.green
Color.blue
Color.yellow
Color.pink
Color.cyan
"""
# purple依舊沒有打印
# 那如果我就想把值相同的也打印出來,要怎么做呢?
# 枚舉內部有一個__members__屬性,相當於一個字典
for c in Color.__members__.items():
print(c[0], c[1])
"""
red Color.red
green Color.green
blue Color.blue
yellow Color.yellow
pink Color.pink
cyan Color.cyan
purple Color.cyan
"""
# 第一個元素是key,str類型。第二個元素是枚舉類型。
# 可以看到最后一個,即便key是purple,但是對應的枚舉類型依舊是Color.cyan
for c in Color.__members__.items():
print(c[0], c[1], c[1].name, c[1].value)
"""
red Color.red red 1
green Color.green green 2
blue Color.blue blue 3
yellow Color.yellow yellow 4
pink Color.pink pink 5
cyan Color.cyan cyan 6
purple Color.cyan cyan 6
"""
# 最后一個打印的仍是cyan
# 成員之前也可以進行比較,但只支持is和==操作符,不支持大小比較
print(Color.green is Color.red) # False
print(Color.green is Color.green) # True
print(Color.cyan is Color.purple) # True
print(Color.cyan == Color.purple) # True
成員的值是否可變
import enum
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = 6
purple = 6
try:
Color.red.name = "xxx"
except Exception as e:
print(e) # can't set attribute
try:
Color.red.value = "xxx"
except Exception as e:
print(e) # can't set attribute
# 可以看到是無法賦值的
import enum
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = []
purple = []
print(Color.cyan is Color.purple) # True
Color.cyan.value.append(123)
print(Color.cyan is Color.purple) # True
"""
可以看到,盡管無法重新賦值,但是本地修改還是可以的,如果是可變類型的話
但是兩個還是一樣的,因為purple是cyan的別名,當在創建這個類的時候,由於都是空列表,所以認為兩者是一樣
因此當我對cyan.value進行append的時候,會影響purple
"""
print(Color.cyan.value) # [123]
print(Color.purple.value) # [123]
Color.purple.value.append(456)
# 通過反過來也是一樣的
print(Color.cyan.value) # [123, 456]
print(Color.purple.value) # [123, 456]
強制讓成員的值不一樣
枚舉類,key重復是不允許的,但是值重復是可以的,可如果我也不允許值重復呢?只需要加上一個裝飾器即可
import enum
try:
@enum.unique
class Color(enum.Enum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = []
purple = []
except Exception as e:
print(e) # duplicate values found in <enum 'Color'>: purple -> cyan
# 提示我們purple和cyan的value重復了
比較成員的值
之前說過,枚舉成員是不支持大小比較的,但如果我想支持呢?
import enum
# 換一種繼承的類,改成IntEnum
class Color(enum.IntEnum):
red = 1
green = 2
blue = 3
yellow = 4
pink = 5
cyan = "6"
# 此時里面的成員要是int類型,或者能將字符串轉成int
print(Color.red < Color.blue) # True
print(Color.red + Color.cyan) # 7