1. 程式人生 > >別再說Python沒有列舉型別了,好好看看

別再說Python沒有列舉型別了,好好看看

開發十年,就只剩下這套架構體系了! >>>   

列舉

列舉型別可以看作是一種標籤或是一系列常量的集合,通常用於表示某些特定的有限集合,例如星期、月份、狀態等。

Python 的原生型別(Built-in types)裡並沒有專門的列舉型別,但是我們可以通過很多方法來實現它,例如字典、類等:

MiracleLove = {'MON': '林志玲', 'TUS': '陳意涵', 'WEN': '張柏芝', 'THU': '辛芷蕾', 'FRI': '周冬雨'}

class MiracleLove:
   MON = '林志玲'
   TUS = '陳意涵'
   WEN = '張柏芝'
   THU = '辛芷蕾'
   FRI = '周冬雨'

上面兩種方法可以看做是簡單的列舉型別的實現。

如果只在區域性範圍內用到了這樣的列舉變數是沒有問題的。

但問題在於它們都是可變的(mutable),也就是說可以在其它地方被修改從而影響其正常使用:

MiracleLove['MON'] = MiracleLove['FRI']
print(MiracleLove)

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

ml = MiracleLove()
print(ml.MON)

MiracleLove.MON = 2
print(ml.MON)

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

MiracleLove = ('R', 'G', 'B')
print(MiracleLove[0], MiracleLove[1], MiracleLove[2])

為了提供更好的解決方案,Python 通過 PEP 435 在 3.4 版本中添加了 enum 標準庫,3.4 之前的版本也可以通過 pip install enum 下載相容支援的庫。

enum 提供了 Enum/IntEnum/unique 三個工具,用法也非常簡單,可以通過繼承 Enum/IntEnum 定義列舉型別,其中 IntEnum 限定列舉成員必須為(或可以轉化為)整數型別,而 unique 方法可以作為修飾器限定列舉成員的值不可重複:

from enum import Enum, IntEnum, unique

try:
   @unique
   class MiracleLove(Enum):
       MON = '林志玲'
       TUS = '陳意涵'
       WEN = '張柏芝'
       THU = '辛芷蕾'
       FRI = '周冬雨'
except ValueError as e:
   print(e)
   
# duplicate values found in <enum 'MiracleLove'>: FRI -> MON
try:
   class MiracleLove(IntEnum):
       MON = 1
       TUS = 2
       WEN = 3
       THU = 4
       FRI = '周冬雨'
except ValueError as e:
   print(e)

# invalid literal for int() with base 10: '周冬雨'

更有趣的是 Enum 的成員均為單例(Singleton),並且不可例項化,不可更改:

class MiracleLove(Enum):
   MON = '林志玲'
   TUS = '陳意涵'
   WEN = '張柏芝'
   THU = '辛芷蕾'
   FRI = '周冬雨'

try:
   MiracleLove.MON = 2
except AttributeError as e:
   print(e)

# Cannot reassign members.

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

mon = MiracleLove(0)
tus = MiracleLove(1)
wen = MiracleLove(2)
print(mon, tus, wen)

# MiracleLove.MON 
# MiracleLove.TUS 
# MiracleLove.WEN

也可以進行比較判斷:

print(mon is MiracleLove.MON)
print(mon == MiracleLove.MON)
print(mon is tus)
print(wen != MiracleLove.TUS)
print(mon == 0) # 不等於任何非本列舉類的值

# True
# True
# False
# True
# False

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

print(mon.TUS)
print(mon.TUS.WEN.MON)

# MiracleLove.TUS
# MiracleLove.MON

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

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

class Attr(Enum):
   name  = 'NAME'
   value = 'VALUE'

print(Attr.name.value, Attr.value.name)

# R : 0
# NAME value

總結:

enum 模組的用法很簡單,功能也很明確,但是其實現方式卻非常值得學習。如果你想更深入瞭解更多 Python 中關於 Class 和 Metaclass 的黑魔法,又不知道如何入手,那麼不妨閱讀一下 enum 的原始碼。

關注公眾號「Python專欄」,後臺回覆「騰訊架構資源1」,獲取由騰訊架構師整理的大資料學習全套資源包!

Pyth   
 
 </div> 
 <div class=

相關推薦

再說Python沒有列舉型別好好看看

開發十年,就只剩下這套架構體系了! >>>   

再說Python沒有枚舉類型好好看看

很多 mut center 圖片 ann 公眾 關註 可以轉化 n) 枚舉類型可以看作是一種標簽或是一系列常量的集合,通常用於表示某些特定的有限集合,例如星期、月份、狀態等。 Python 的原生類型(Built-in types)裏並沒有專門的枚舉類型,但是我們可以通過

JAVA 8 的Stream API操作使用if-else迴圈

在這篇文章裡,我們將會去了解傳統迴圈的一些替代方案。在Java 8的新功能特性中,最棒的特性就是允許我們去表達我們想要完成什麼而不是要怎樣做。這正是迴圈的不足之處。要確保迴圈的靈活性是需要付出代價的。return、break 或者 continue都會顯著地改變迴圈的實際表現。這迫使我們不僅

吐槽明日之後這些國產末日生存手遊你會感謝網易的

明日之後好玩嗎?最近看到很多人各種吐槽明日之後,什麼氪金啊,肝啊等等,在各大平臺的評分也被刷到很低。可是大部分人都是嘴上說著不要,身體卻很誠實,每天都要肝幾個小時,好多人別墅都建好了,充值的人也不在少數。 我想說的是明日之後評分被刷這麼低的原因大部分是因為之前內測的風波和公測時伺服器崩潰,不是因

求你不要在對外介面中使用列舉型別

[GitHub 18k Star 的Java工程師成神之路,不來了解一下嗎!](https://github.com/hollischuang/toBeTopJavaer) [GitHub 18k Star 的Java工程師成神之路,真的不來了解一下嗎!](https://github.com/hollis

拜託面試問我基數排序!!!

排序,面試中考察基本功問的比較多,工作多年以後,對排序的細節記憶不那麼清楚的小夥伴,面試時會比較吃虧。 有一種很神奇的排序,基數排序(Radix Sort),時間複雜度為O(n),今天花1分鐘,通過幾幅圖,爭取讓大家搞懂細節。   畫外音:居然還有時間複雜度為O(n)

關於最近一篇 "盯著我們看" 92年女生致周鴻禕公開信事件我想說點什麼!

本來不想寫這篇文章的,因為我覺得我的公眾號一定要發技術乾貨和福利的,但是最近這件事我看不下去了,

沒解決這3個問題扯系統高可用

  作者:王曄倞 連結:https://dbaplus.cn/news-141-2712-1.html 上個月,我

「C++ 篇」答應我if/else走天下可以嗎

每日一句英語學習,每天進步一點點: "Without purpose, the days would have ended, as such days always end, in disintegration." 「少了目標,一天還是會結束,它總是以支離破碎的形式結束。」 前言 羊哥之前寫一篇有

使用Spring Cloud Config統一管理配置到處放配置檔案

# 1 前言 > 歡迎訪問[南瓜慢說 www.pkslow.com](https://www.pkslow.com/)獲取更多精彩文章! 可配置是一個成熟軟體系統應該提供的特性,而配置管理對於大型系統就顯得十分重要,特別是對於擁有多個應用的微服務系統。可喜的是,`Spring`為我們提供了很好的配

求求你用wait和notify

`Condition` 是 JDK 1.5 中提供的用來替代 `wait` 和 `notify` 的執行緒通訊方法,那麼一定會有人問:**為什麼不能用 `wait` 和 `notify` 了?** 哥們我用的好好的。老弟彆著急,聽我給你細說... 之所以推薦使用 `Condition` 而非 `Objec

在看不起女程序媛一個高顏值女程序媛的日常

歷史 所見 嘗試 女生 tro 想想 不堪 標簽 集中 我的日常 日常的上班狀態是這樣的 早晨到公司,打開電腦,打開知乎微博簡書先刷一遍,然後進入狀態,開始敲代碼,做自己的項目,在這個過程之中,上面扔過來一張圖,來我要這個這個效果,後臺發來一條消息,這有個不是後臺的bu

連續加班一周最終把所有的Python庫整理出來願各位早日學會Python

das 三維 定義 crypt 生產者 密碼 過濾器 循環 gui 我們直接開始主題,小夥伴們需要資料的話可以私信我回復01,可以獲得大量PDF書籍和視頻! Python常用的庫簡單介紹一下 fuzzywuzzy ,字符串模糊匹配。 esmre ,正則表達式的

使用Python一年多總結八個好用的Python爬蟲技巧

用python也差不多一年多了,python應用最多的場景還是web快速開發、爬蟲、自動化運維:寫過簡單網站、寫過自動發帖指令碼、寫過收發郵件指令碼、寫過簡單驗證碼識別指令碼。 爬蟲在開發過程中也有很多複用的過程,這裡總結一下,以後也能省些事情。 1、基本抓取網頁 get方法

使用pip安裝TensorFlow!用conda吧

目錄 1、更快的 CPU 效能 2、GPU 版本的安裝也更加簡單 3、快速啟動 conda 是一個開源包和環境管理系統,能夠跨平臺執行,在 Mac、Windows 和 Linux 上都可以執行。如果你還沒用過 conda,我推薦你立刻開始使用,因為它會讓管理資料科學工具變得更輕鬆。

python高階語法-python3你還在用%和format格式化輸出嗎

在之前的一段時間python2.x的時代,字串的格式化輸出有兩種方式 第一種 %來格式化輸出 str1 = "i am %s" % "Zc" print(str1) 第二種 利用format來格式化定義 str2 = "i am {}".format("Zc"

當 map 的 value 只是整數沒有別的型別將 map string 轉成 map

    /**      * 當  map 的 value 只是整數,沒有別的型別時,將 map string 轉成 map      */     public static Map<String, Object> mapStrToMap( String map

拜託,面試讓我數1!!!

面試中,除了TopK,是否被問過:求一個正整數的二進位制表示包含多少個1? 例如: uint32_t i=58585858; i的二進位制表示是: 0000 0011 0111 1101 1111 0011 0000 0010 於是,i的二進位制表示包含15個

Python列舉型別

起步 Python 的原生型別中並不包含列舉型別。為了提供更好的解決方案,Python 通過 PEP 435 在 3.4 版本中添加了 enum 標準庫。 列舉型別可以看作是一種標籤或是一系列常量的集合,通常用於表示某些特定的有限集合,例如星期、月份、

經濟學家都用在用Python分析房價走勢哪裡跌價買哪裡!

學習Python中有不明白推薦加入交流裙                 號:735934841                 群裡