PyTips 0x17 Python 中的列舉型別

2021-09-19 09:07:46 字數 2591 閱讀 8762

列舉型別可以看作是一種標籤或是一系列常量的集合,通常用於表示某些特定的有限集合,例如星期、月份、狀態等。python 的原生型別(built-in types)裡並沒有專門的列舉型別,但是我們可以通過很多方法來實現它,例如字典、類等:

weekday = 

class color:

red = 0

green = 1

blue = 2

上面兩種方法可以看做是簡單的列舉型別的實現,如果只在區域性範圍內用到了這樣的列舉變數是沒有問題的,但問題在於它們都是可變的(mutable),也就是說可以在其它地方被修改從而影響其正常使用:

weekday['mon'] = weekday['fri']

print(weekday)

通過類定義的列舉甚至可以例項化,變得不倫不類:

c = color()

print(c.red)

color.red = 2

print(c.red)

0

2

當然也可以使用不可變型別(immutable),例如元組,但是這樣就失去了列舉型別的本意,將標籤退化為無意義的變數:

color = ('r', 'g', 'b')

print(color[0], color[1], color[2])

r g b
from enum import enum, intenum, unique

try:

@unique

class weekday(enum):

mon = 1

tus = 2

wen = 3

thu = 4

fri = 1

except valueerror as e:

print(e)

duplicate values found in : fri -> mon
try:

class color(intenum):

red = 0

green = 1

blue = 'b'

except valueerror as e:

print(e)

invalid literal for int() with base 10: 'b'
更有趣的是enum的成員均為單例(singleton),並且不可例項化,不可更改:

class color(enum):

r = 0

g = 1

b = 2

try:

color.r = 2

except attributeerror as e:

print(e)

cannot reassign members.
雖然不可例項化,但可以將列舉成員賦值給變數:

red = color(0)

green = color(1)

blue = color(2)

print(red, green, blue)

color.r color.g color.b
也可以進行比較判斷:

print(red is color.r)

print(red == color.r)

print(red is blue)

print(green != color.b)

print(red == 0) # 不等於任何非本列舉類的值

true

true

false

true

false

最後一點,由於列舉成員本身也是列舉型別,因此也可以通過列舉成員找到其它成員:

print(red.b)

print(red.b.g.r)

color.b

color.r

但是要謹慎使用這一特性,因為可能與成員原有的命名空間中的名稱相衝突:

print(red.name, ':', red.value)

class attr(enum):

name = 'name'

value = 'value'

print(attr.name.value, attr.value.name)

r : 0

name value

C 中 x與0x的區別

首先這兩個均表示16進製制,但是用法有所不同。x主要是用於字元的表示 如char ch xa 那麼ch這個字元所代表的是什麼呢?正如上面所說的 x代表的是16進製制,16進製制中的a在十進位制中代表10,那麼ch這個數就代表著序號為10的ascii碼所代表的字元,即 n換行符。0x雖然也代表十六進製...

C 0 x中 C 的未來

0 x的工作名稱的新標準c 增加了許多,我將在這一系列c 11的語言功能。2011年9月,c 0 x的正式出版為新的c 11標準,現在許多編譯器提供了一些核心c 11功能的支援。c 11包括廣泛的特點 主要的新功能,像拉姆達的支援和 移動語義 通過自動關鍵字型別推斷可用性改進,例如,簡化迴圈容器,許...

C 0x11中列舉的問題

c 11中新增的強型別列舉,確實可以解決此前版本中列舉的作用域問題,但是隨之也帶來一些其他問題。強型別列舉的宣告方式為 enum class enumname value1,value2 在編碼中,我以前比較習慣對列舉值應用位運算,比如 和 但是對於c 11中的強型別列舉,則無法再應用位運算。比如 ...