Microsoft Enumeration Guide
enum
讓程式碼更清晰、好讀,尤其是你管理的常數名稱有意義的情況
Python 中的 enum
套件來自 Enumerate 的縮寫,中文可以翻譯為枚舉,功能是讓多個常數值綁定在特定符號組合(例如 1、2、3)。如果你在程式中的某個變數,其被指定的值是來自特定且有限的幾種數值,這時候就很適合使用 enum
來幫助你把程式變漂亮。
我開始學習使用 Python enum
的契機是 2021 年剛加入這間 科技公司 工作時,某次與軟體工程師會議中,在討論 App 產品中的 字重(font weight)資料埋點該如何設計,以了解使用者對特定字體粗細設定的偏好。其中一位工程師提出一個直覺的作法:在 Log 中以整數(Integer)紀錄使用者正在用的字重,雖然我當時覺得可行、立刻同意,然而,另一位較資深的工程師則提出:由於字重只有特定幾種常數值,包括 300、400、500 等等(而不會有 “471” 這種字重數值),所以,這個情境要用 enum
來表述資料會更適當!
這則筆記整理了我在上面這項經歷後持續鑽研的 Python enum
用法,我將與你分享用 enum
究竟有什麼好處,文章內也將教學 Python enum
的基本與進階使用技巧。
enum
的使用不只對 Python 設計 App 產品有幫助,資料科學家們也可以透過 enum
讓 pandas
分析巨量資料時更有效率!本篇筆記也會分享在 pandas
內使用 enum
的組合技巧,提供一個讓計算速度提升 5 倍的範例,如果你是資料科學愛好者,想必你會有興趣讀下去!
閱讀提醒:
- 本文討論的是
enum
套件,而不是enumerate()
函式,這兩者只是名字長得像、但功能大不相同喔! Enum
與enum
是不一樣的。enum
指的是套件(package),Enum
是套件中一個類別(Class),只是Enum
類別十分常用,所以本文內文可能會有混用的情形,請稍微注意
目錄
為什麼需要枚舉與 Enum
?
使用 enum
來枚舉實際上做的事情,可以簡單理解為:管理一群「成員名稱與成員數值」的對應關係。當你要管理的常數有特定對象、而且數量有限時,特別實用,例如:
- 月份資料(只有十二個月):成員
November
對應到數值11
- 顏色資料(常用的是 RGB 三種原色):成員
Green
對應到數值2
- 衣服尺碼資料(從 S 到 XL):成員
Small
對應到數值1
- 本文前言提過的字重資料(100、200、300 等):成員 400 對應到
4
比起直接開始宣揚 enum
的好處,我們先從一個簡單的例子來看看沒有使用 enum
會有什麼壞處:
employee = "data scientist"
if employee == "Engineer":
print("此員工是一位:" + "工程師")
elif employee == "Product Manager":
print("此員工是一位:" + "產品經理")
elif employee == "Data Scientist":
print("此員工是一位:" + "資料科學家")
else:
print("未知的職位")
想想看,你覺得這支超簡單的程式會在畫面上輸出什麼結果呢?跑跑看便知道,答案是 未知的職位
。
我明明將變數設定成 data scientist
了,在我的 if-else 條件式裡面明明也有包含這個職位,為什麼還是輸出 未知的職位
?問題很基本:單純是大小寫不同。
>>> "Data Scientist" == "data scientist"
False
「資料科學家」在程式內用英文表述可能是 Data Scientist
、data scientist
、也可能是 Data scientist
,只有人類看起來意思一樣,程式看起來可是完全不同數值。不同的工程師來寫這支程式,依照個人習慣會有不同表述方法,更慘的是,像上面這種寫法,很容易有錯字(Typo)!
>>> "Data Scientist" == "Data Sciantist" # 眼力大考驗 (˚∀˚)
False
上面的情境正是 enum
能解決的痛點,在 Python 使用 enum
的主要好處是:
- 增加程式的可讀性(Readability)、讓程式更好維護
enum
排除了手動輸入常數打錯字的可能性- 變數可能呈現的常數選項變得更一目瞭然、更好管理
- 例如:避免共同設計此程式的其他工程師寫出不符合規定的常數
在概念上,enum
會把以上範例改寫成:
- 用數字 1 代表「工程師」
- 用數字 2 代表「產品經理」
- 用數字 3 代表「資料科學家」
使用後 enum
後,這支處理職位資訊的程式範例會得到的好處是:
- 職位名稱與職位數字對應關係是固定的,對應關係以外的都不能用,因此不用怕輸入常數的打字錯誤
- 不再煩惱該寫
Data Scientist
還是data scientist
,因為最後只會有其中一種被允許使用
- 不再煩惱該寫
- 不被
enum
管理的職位,就不能(隨意)使用,除非程式設計者加入新職位- 範例中只有 3 個職位,如果你想在職位中使用數字 4 代表「業務員」的話,
enum
會告訴你違規了!
- 範例中只有 3 個職位,如果你想在職位中使用數字 4 代表「業務員」的話,
以上都是概念性地介紹 enum
,接下來的筆記會正式開始介紹 Python 中 enum
的操作語法,你將會在語法中更清楚看到使用 enum
的優點。
在此,筆者好豪簡短補充,枚舉(Enumerated Type)是一種程式中表述資料的方法,而不是 Python 獨有的技巧,各個程式語言都有各自的枚舉語法,而 Python 是用enum
套件來做到枚舉。
Python Enum
語法教學
現在我們用 Python 的 enum
來實作以上範例來當作枚舉語法教學,我想用 enum
來管理代表「職業」的常數成員:
from enum import Enum
class Job(Enum):
ENGINEER = 1
PRODUCT_MANAGER = 2
DATA_SCIENTIST = 3
在此再次提醒 Enum
與 enum
不一樣喔,enum
指的是套件(package),Enum
是其中最常用到的一個類別(Class)。
前面提過,枚舉是在管理一群「成員名稱與成員數值」的對應關係,比如說範例中的 ENGINEER
是成員名稱、1
是它對應的成員數值。在 Python 使用枚舉時,需要創造一個子類別、繼承自 Enum
這個類別,Python 的語法糖讓創造枚舉的子類別變得超級簡單,只要寫上 成員名稱 = 成員數值
即可,成員要增減都十分簡潔。
成員數值使用 int
(整數),並且使用序號(照 1、2、3 順序)只是常見的用法,實際上,你為成員數值設計的整數值不一定要照順序(例如 DATA_SCIENTIST = 168
)。
現在我們可以用操作類別屬性(Attribute)的方式來操作枚舉與其成員了:
## 枚舉成員的型別正是我們創造的 Enum 子類別
>>> Job.DATA_SCIENTIST
<Job.DATA_SCIENTIST: 3>
>>> type(Job.DATA_SCIENTIST)
<enum 'Job'>
Enum
子類別雖然可以比較是否相等,但是不能比大小。也須注意比較對象究竟是成員名稱還是數值:
## Enum 可以用 == 或 is 比較是否相等
>>> Job.ENGINEER == Job.ENGINEER
True
>>> Job.ENGINEER is Job.ENGINEER
True
>>> Job.ENGINEER != Job.ENGINEER
False
>>> Job.ENGINEER is Job.PRODUCT_MANAGER
False
## 但是不能比大小
>>> Job.ENGINEER < Job.PRODUCT_MANAGER
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'Job' and 'Job'
## 雖然 ENGINEER 確實被賦予數值 1
## 但是「成員」(Enum 子類別)與「成員數值」型別不一樣
## 所以結果當然不可能相等
>>> Job.ENGINEER == 1
False
>>> type(Job.ENGINEER)
<enum 'Job'>
>>> type(1)
<class 'int'>
Enum
資料的操作方式很像是 namedtuple
,例如我們創造的 Enum
子類別會有 name
與 value
屬性:
>>> Job.DATA_SCIENTIST.name
'DATA_SCIENTIST'
>>> Job.DATA_SCIENTIST.value
3
筆者好豪認為 Enum
比 namedtuple
好用的地方在於 Enum
的 name
與 value
可以雙向訪問,也就是,使用 namedtuple
通常只能根據 name
取得 value
,而 Enum
反過來也做得到:
(這項雙向訪問的特性,本文後續介紹的 pandas
+ Enum
的運算加速組合技巧 馬上就會用到!)
## 根據 name 取得 value:類別屬性的操作方式
>>> Job.DATA_SCIENTIST
<Job.DATA_SCIENTIST: 3>
## 根據 name 取得 value:像 dict 一樣用字串存取
>>> Job['DATA_SCIENTIST']
<Job.DATA_SCIENTIST: 3>
## 根據 value 也能取得 name
>>> Job(3)
<Job.DATA_SCIENTIST: 3>
可以用 list
來秀出所有枚舉成員,或者用迴圈遍歷整個枚舉:
>>> list(Job)
[<Job.ENGINEER: 1>, <Job.PRODUCT_MANAGER: 2>, <Job.DATA_SCIENTIST: 3>]
>>> for job in Job:
... print(job)
Job.ENGINEER
Job.PRODUCT_MANAGER
Job.DATA_SCIENTIST
宣告 Enum
子類別後,不包含在枚舉成員中的內容,當然就無法存取囉,換句話說,當你不小心打錯字、或是使用不合理的成員資料時,不用等到程式執行、Python 會在你寫程式的過程(例如在 IDE 介面內)就跟你抱怨!
## 沒有這個成員 -> 程式錯誤!
>>> Job.ACCOUNT_MANAGER
Traceback (most recent call last):
...
AttributeError: ACCOUNT_MANAGER
## 就算成員名稱正確、大小寫不一致也不行 -> 程式錯誤!
>>> Job.Data_Scientist
Traceback (most recent call last):
...
AttributeError: Data_Scientist
## 不存在數值為 42 的成員 -> 程式錯誤!
>>> Job(42)
Traceback (most recent call last):
...
ValueError: 42 is not a valid Job
Enum
運用範例:Tensorflow Lite
TensorFlow Lite 是知名的機器學習套件 TensorFlow
的延伸,用於在行動裝置或其他邊緣裝置上部署機器學習模型。
TensorFlow Lite 在定義最佳化(Optimize)選項時,運用了 Python 的 enum
套件。以下是擷取 此 Commit 的簡化版程式碼:
class Optimize(enum.Enum):
DEFAULT = "DEFAULT"
OPTIMIZE_FOR_SIZE = "OPTIMIZE_FOR_SIZE"
OPTIMIZE_FOR_LATENCY = "OPTIMIZE_FOR_LATENCY"
EXPERIMENTAL_SPARSITY = "EXPERIMENTAL_SPARSITY"
此枚舉主要會被其他函式呼叫的參數設定所用,例如 QuantizationMode
的參數 就用到此枚舉(經些微改寫):
lite.QuantizationMode(
[lite.Optimize.OPTIMIZE_FOR_LATENCY],
lite.TargetSpec(), None, None)
從此案例,我們可以學到兩個使用 enum
的技巧:
- 枚舉很適合用在函式呼叫的參數(Parameter)設定,尤其是參數只可能是特定幾種數值時
- 上述範例中,Tensorflow Lite 需要的最佳化總共只有 4 種,因此用
Enum
來妥善管理這 4 個成員
- 上述範例中,Tensorflow Lite 需要的最佳化總共只有 4 種,因此用
Enum
的成員數值除了int
(整數)以外,str
(字串)也可用
Python Enum
的寫程式慣例
在 Python 程式內使用 enum
時,有一些常見、但是非強制要求的寫程式慣例(Coding Conventions),不遵守這些慣例並不會造成程式出現 bug,但是這些慣例通常也是大多數程式設計師的習慣、所以遵守慣例會讓程式更好讀。在此,筆者好豪分享兩個使用 enum
的慣例:
序號從 1 開始
首先,如果你的成員數值是int
(整數)型別、並且需要序號排列(照 1、2、3 順序),建議從 1 開始、而不從 0 開始。其理由是 Python 將 0 視為布林值的 False
,但枚舉的成員按理來說,數值都應該要是 True
。例如,以下改寫「職業」的枚舉範例、令數值從 0 開始:
class Job(Enum):
ENGINEER = 0
PRODUCT_MANAGER = 1
DATA_SCIENTIST = 2
即使我們妥善設定了成員名稱與數值,從 0 開始的成員數值會出現以下這種詭異的情形:
>>> for job in Job:
... if job.value:
... print(job.name)
... else:
... print("???")
???
PRODUCT_MANAGER
DATA_SCIENTIST
這當然不是什麼太常見的用法情境,但是為了避免萬一真的發生、又要燒腦找 Bug 的尷尬狀況,我們就乖乖從 1 開始設定成員數值吧。
auto()
既然提到成員數值從 1 開始的話題,我覺得在此很適合介紹另外兩種 enum
套件內宣告 Enum
子類別的做法,因為這兩個做法雖然都不需要明確在程式碼寫出成員數值,但它們都遵從「成員數值從 1 開始」的慣例!
第一,是使用 auto()
,如果你對成員數值沒有特別要求,auto()
可以自動幫你創造代替成員數值的實例(Instance)。
from enum import Enum, auto # 注意 auto 需要額外 import
class Job(Enum):
ENGINEER = auto()
PRODUCT_MANAGER = auto()
DATA_SCIENTIST = auto()
auto()
會自動幫你在成員數值補上 1、2、3 等等整數值:
>>> Job.ENGINEER
<Job.ENGINEER: 1>
>>> list(Job)
[<Job.ENGINEER: 1>, <Job.PRODUCT_MANAGER: 2>, <Job.DATA_SCIENTIST: 3>]
第二,功能性 API 讓你用 Enum( 子類別名稱, 列舉所有成員的字串 )
的語法來更簡潔地創造枚舉,如下範例:
## Enum( 子類別名稱, 列舉所有成員的字串 )
>>> Job = Enum("Job", "ENGINEER PRODUCT_MANAGER DATA_SCIENTIST")
>>> Job.ENGINEER
<Job.ENGINEER: 1>
>>> list(Job)
[<Job.ENGINEER: 1>, <Job.PRODUCT_MANAGER: 2>, <Job.DATA_SCIENTIST: 3>]
成員名稱全部大寫
第二個建議採用的 enum
寫程式慣例:成員名稱全部都大寫。
枚舉所要管理的是一群常數,而 Python 最重要的寫程式風格指南 PEP8 當中規範,常數的命名需要是全部大寫並且以底線(_
)分隔,例如 DATA_SCIENTIST
符合此規範,DataScientist
則不符合。若想知道更多命名慣例以及遵守慣例的好處,我覺得 此表格 相當一目了然。
當然,你不遵守這個命名慣例,enum
程式還是可以運行、不會有 Bug:
class Job(Enum):
Engineer = 42
ProductManager = 94666
DataScientist = 168
>>> Job.DataScientist
<Job.DataScientist: 168>
只不過,如果能遵守慣例的話,閱讀你程式的其他工程師,可以少花一些時間困惑、不用擔心你的程式是否有什麼特殊用意。
三個 Python Enum 進階技巧
學會基礎語法後,我將接著分享自己在實戰中常用到的 Enum
運用技巧。
__str__()
讓常數顯示變美麗
__str__()
是 Enum
支援的其中一種 雙底線方法(Dunder Method),它的功能是幫助你設定 print()
此物件的如何呈現的格式設定。
我們上個小節剛提過 Enum
建議把常數全部用大寫來命名,這項慣例對程式設計師有好處、對程式使用者則不見得,如果你覺得呈現給使用者全部大寫的字串不夠美觀,這時可以用 __str__()
來調整:
class Job(Enum):
ENGINEER = 1
PRODUCT_MANAGER = 2
DATA_SCIENTIST = 3
def __str__(self):
return ' '.join([x.capitalize() for x in self.name.split('_')])
## 我個人覺得 "Data Scientist" 比 "DATA_SCIENTIST" 順眼
## 你覺得呢 (´・ω・`)?
>>> print(Job.DATA_SCIENTIST)
Data Scientist
>>> print(f"Wilson is a {Job.DATA_SCIENTIST}.")
Wilson is a Data Scientist.
## 是不是比 "Wilson is a DATA_SCIENTIST." 好看多了?
延伸閱讀:不只 __str__()
,Python 還有 許多種「底線」使用方法
以 unique
避免成員數值重複
在預設狀況下,Enum
不允許重複的成員名稱,程式會出錯:
>>> class Job(Enum):
... ENGINEER = 1
... PRODUCT_MANAGER = 2
... DATA_SCIENTIST = 3
... DATA_SCIENTIST = 4
... DATA_SCIENTIST = 5
Traceback (most recent call last):
...
TypeError: Attempted to reuse key: 'DATA_SCIENTIST'
然而,Enum
允許有重複的成員數值,這種作法稱之為別名(Alias)。使用別名的話,相同成員數值的成員在 Enum
內都會被指向同一個成員,因此可能會產生容易令人誤會的結果。
以下範例中,ENGINEER
與 DATA_SCIENTIST
使用相同的成員數值 42
,在此情況,在程式碼行數順序中、比較晚宣告的成員都會變成第一個宣告成員的別名,因此,DATA_SCIENTIST
變成了 ENGINEER
的別名,嘗試用 Enum
存取 DATA_SCIENTIST
時,實際取得的卻是 ENGINEER
,會讓人感到困惑:
class Job(Enum):
ENGINEER = 42
PRODUCT_MANAGER = 2
DATA_SCIENTIST = 42
>>> Job.ENGINEER
<Job.ENGINEER: 42>
>>> Job.DATA_SCIENTIST
<Job.ENGINEER: 42>
>>> Job.DATA_SCIENTIST.name
'ENGINEER'
承前面所學,auto()
是一個簡單的解法,因為 auto()
不只讓你不用手動輸入成員數值,它自己會產生不重複的成員數值、已經幫你避免別名發生了。
如果你仍需要自己設定成員數值,又不想發生重複成員數值,可以用 unique
裝飾器(Decorator)來禁止別名,使用此裝飾器後,要是 Enum
內發現重複成員數值,會產生 ValueError
:
## 這段程式碼跟正上方的範例
## 主要差別只有 `@unique` 這一行而已
>>> from enum import Enum, unique # 注意 unique 需要額外 import
>>> @unique
... class Job(Enum):
... ENGINEER = 42
... PRODUCT_MANAGER = 2
... DATA_SCIENTIST = 42
Traceback (most recent call last):
...
ValueError: duplicate values found in <enum 'Job'>: DATA_SCIENTIST -> ENGINEER
補充:即使 unique
禁止重複成員數值,有心人士仍能用繼承子類別的方式「繞過」此禁令,要是你需要嚴格到連子類別繼承都不可使用別名,可以參考官方文件的 DuplicateFreeEnum 作法。
用 Enum
加速 pandas
資料運算
本文曾提及,當你儲存的資料是特定且有限的幾個常數,格外適合使用 Enum
,這個情境在資料分析經常出現。以下範例我們創造了有一百萬筆資料的員工每日工作時數資料,其中,職業(job)這行資料,即使有一百萬筆資料、實際上只有 3 種類別:
## 創造範例資料
import pandas as pd
import numpy as np
data_size = 1_000_000
np.random.seed(42)
df = pd.DataFrame()
df['job'] = np.random.choice(['ENGINEER', 'PRODUCT_MANAGER', 'DATA_SCIENTIST'], data_size)
df['age'] = np.random.randint(1, 50, data_size)
df['work_hour'] = np.random.normal(8, 3, data_size)
(如果你沒看過 1_000_000
這種底線用法,這篇 Python 底線教學 有更多說明)
## 快速瀏覽資料
>>> df.head()
job age work_hour
0 DATA_SCIENTIST 32 6.585159
1 ENGINEER 19 1.270486
2 DATA_SCIENTIST 36 10.266954
3 DATA_SCIENTIST 43 10.461590
4 ENGINEER 28 10.306234
## 職業(Job)總共只有 3 種
>>> df['job'].unique()
array(['DATA_SCIENTIST', 'ENGINEER', 'PRODUCT_MANAGER'], dtype=object)
假設,現在我們的資料分析任務是「計算所有員工的平均每日工作時數」,使用 pandas
我們的計算方法只需一行就能完成 df.groupby('job')['work_hour'].mean()
。在此小節,我們不在乎這個假想資料的計算結果,我們在乎的是運算所花費的時間。
以下,我將使用 Google Colab 裡面超好用的 %timeit
指令 來衡量我們的分析任務需要花費多少時間:
>>> %timeit df.groupby('job')['work_hour'].mean()
58.4 ms ± 9.58 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
這裡可以解讀為:Colab 為我們反覆執行這行分析任務多次,算出平均運算時間是 58.4 毫秒。
(延伸閱讀:在 Google Colab 用神奇的「魔法」指令結合 Python 與 Command Line)
以上這段分析任務,存在很大的加速空間。資料中的職業(job)明明只有 3 種,卻反覆用 str
(字串)型別儲存了一百萬次,事實上很多餘、會對 pandas
造成不必要的負擔。
透過我們在 Enum
學會的做法,我們可以將資料中的職業從 str
轉換成用 int
,並用 Enum
妥善管理職業成員以及轉換原則:
class Job(Enum):
ENGINEER = 1
PRODUCT_MANAGER = 2
DATA_SCIENTIST = 3
def __str__(self):
return ' '.join([x.capitalize() for x in self.name.split('_')])
我們將範例資料中的職業欄位用 Enum
轉換成 int
型態:
>>> df['job'] = df['job'].apply(lambda x: Job[x].value)
>>> df.head()
job age work_hour
0 3 32 6.585159
1 1 19 1.270486
2 3 36 10.266954
3 3 43 10.461590
4 1 28 10.306234
現在,我們再次用 Colab 中的 %timeit
指令來重新衡量計算時間,看看分析任務運算速度是否有變化:
>>> %timeit df.groupby('job')['work_hour'].mean()
11.1 ms ± 130 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
分析任務的平均運算時間變成了 11.1 毫秒。跟剛剛的 58.4 毫秒相比,我們可以說,透過 Enum
把職業欄位從 str
轉換成 int
型別後,計算速度加快了 5 倍之多!
千萬別覺得只有幾毫秒之差乍看之下不多,在職場實戰中,遇到資料庫動輒幾十億筆的資料,如果可以做到這般計算最佳化,可能讓你省下好幾小時的計算時間!
做了轉換後,你又或許會覺得資料不太美觀,例如,看不出來 1、2、3 分別代表什麼職業。其實只要應用這則筆記 前面提到 的 name
與 value
雙向訪問,很輕易地就能把資料轉換回好閱讀的格式:
## 看不出來 1、2、3 代表什麼職業
>>> df.groupby('job')['work_hour'].mean()
job
1 7.989738
2 8.006799
3 8.000956
Name: work_hour, dtype: float64
## 用 Job(2) 這種語法就能簡單地轉換回來
>>> result_df = df.groupby('job')['work_hour'].mean().reset_index()
>>> result_df['job'] = result_df['job'].apply(lambda x: str(Job(x)))
>>> result_df
job work_hour
0 Engineer 7.989738
1 Product Manager 8.006799
2 Data Scientist 8.000956
(小細節:稍早宣告 Enum
子類別時有寫出 __str__()
,才得以讓這裡轉換的字串更美觀喔)
補充:
讀到這裡的你如果已經有些數據分析經驗了,也許會察覺,若目標是把職業欄位從 str
轉換成 int
,用 dict
就能輕易達成了,像是寫成:{'ENGINEER': 1, ...}
。沒錯,光是這麼做的確能夠達成跟前面一樣讓 pandas
加速運算 5 倍的效果。
不過,比起 dict
,使用 Enum
的還有額外好處,包括:
- 當你需要再從
int
轉換回str
時,不需要另外創造一個{1: 'ENGINEER', ...}
的dict
Enum
的成員管理更嚴謹,本文提過的避免輸入錯字與無效成員等好處,可以讓你的資料工作流(Data Pipeline)更加強健、不容易出錯,程式碼也更好維護
但缺點是 Enum
要寫的程式碼比 dict
稍微多一點。
結語
使用 Python 的 enum
套件來達成枚舉,幫助你更好管理一群「成員名稱與成員數值」的對應關係,當你需要管理的常數值集合數量有限的情境,Enum
相當好用。只要搭配好常數命名大寫、還有成員數值序號從 1 開始等慣例,enum
最大的優點是讓你的程式可讀性更高,減少 Bug 出現率。
最後,使用 Enum
的時機還是需要權衡的,當然不是任何用到常數的場合都適合用 Enum
。我認為,只有你的程式設計到了重視可讀性與程式碼品質的階段時,多打幾行程式設計 Enum
子類別才有效益,舉例來說,如果你的工作是探索資料,既不在乎運算速度、也不在乎結果的 可重現性、程式碼也不需要版本控制,這種時候也不見得需要多寫 Enum
來處理。
參考資料:
- Python Enum 官方文件
- PEP8
- Microsoft – When to Use an Enumeration
還想知道更多 Python 相關技巧嗎?推薦你閱讀好豪的其他 Python 分享文章,學會更多實用程式設計方法:
- Python 自學資源分享:幫你找出最有成就感的學習路線!
- Python 函式 zip() 教學:同時迭代多個 list,學習刷題與資料分析技巧
- Python dict 預設值技巧,key 找不到也不用擔心
- Python 函式的可變物件預設引數陷阱
也感謝你閱讀這篇筆記,歡迎追蹤 好豪的粉絲專頁,我會持續分享 Python 技巧、資料科學等知識;歡迎點選下方按鈕將本文加入書籤、或者分享給更多正在學 Python 的朋友。