2021年4月19日 星期一

[ Python 文章收集 ] enum — 枚舉型態用法介紹

 Source From Here

Preface
enum 是 Python 裏用來建立枚舉形態的標準函式庫。enum 算是比較新的標準函式庫,學習 enum 可以讓你輕鬆建立枚舉,改寫以前單獨使用 const variable 的狀況:
An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.

Quickstart Tutorial
從今天開始,讓我們把這樣枚舉的 Code:
  1. # -*- coding: utf-8 -*-  
  2.   
  3. # Input Type  
  4. TRACK = 'track'  
  5. ALBUM = 'album'  
  6. ARTIST = 'atrist'  
  7. PLAYLIST = 'playlist'  
  8.   
  9. # Response Type  
  10. OK = 'ok'  
  11. NO_RESULT = 'no_result'  
使用 enum 來改寫:
  1. # -*- coding: utf-8 -*-  
  2.   
  3. from enum import Enum  
  4.   
  5. class InputType(Enum):  
  6.     TRACK = 'track'  
  7.     ALBUM = 'album'  
  8.     ARTIST = 'atrist'  
  9.     PLAYLIST = 'playlist'  
  10.   
  11. class ResponseType(Enum):  
  12.     OK = 'ok'  
  13.     NO_RESULT = 'no_result'  
之後就可以改用 enum 來比對型態:
>>> InputType.ARTIST == InputType.ALBUM
False
>>> InputType.ARTIST == InputType.ARTIST
True
>>> ResponseType.OK == ResponseType.NO_RESULT
False

透過 enum member 可以取得 name 或是 value:
>>> InputType.PLAYLIST.name
'PLAYLIST'

>>> InputType.PLAYLIST.value
'playlist'

透過 enum class 可以取得 enum member:
>>> InputType('playlist')
<InputType.PLAYLIST: 'playlist'>

>>> InputType['PLAYLIST']
<InputType.PLAYLIST: 'playlist'>

不同的 enum class 雖然有相同的 enum value,但比較結果是不相同的:
  1. >>> import enum  
  2. >>> class Shape(enum.Enum)  
  3. ...     SQUARE = 1  
  4. ...     CIRCLE = 2  
  5. ...  
  6. >>> class Response(enum.Enum):  
  7. ...     OK = 1  
  8. ...     BAD = 2  
  9. ...  
  10. >>> Shape.SQUARE == Response.OK  
  11. False  
“可是我有 legacy code 啊,改成使用 enum 就壞掉了!” 沒關係,透過 globals() 就可以 hack 過去了:


其實應該要透過 globals() + IntEnum 才能直接將 enum member 當 int 用:
  1. >>> class Animal(IntEnum):  
  2. ...     DOG = 1  
  3. ...     CAT = 2  
  4. ...     PANDA = 3  
  5. ...  
  6. >>> globals().update(Animal.__members__)  
  7. >>> DOG  
  8. <Animal.DOG: 1>  
  9. >>> DOG == 1  
  10. True  
  11. >>>  
HOW-TO Guides

使用 IntEnum 來簡化整數枚舉比對
透過 IntEnum 我們可以讓整數枚舉的比對變得更輕鬆一點:
  1. >>> import enum  
  2. >>> class Shape(enum.IntEnum):  
  3. ...     SQUARE = 1  
  4. ...     CIRCLE = 2  
  5. ...     TRIANGLE = 3  
  6. ...  
  7. >>> Shape.SQUARE == 1  
  8. True  
  9. >>> Shape.CIRCLE == 2  
  10. True  
  11. >>> Shape.TRIANGLE == 1  
  12. False  
此時不同 enum class 的比較會是相等的:
  1. >>> import enum  
  2. >>> class Mac(enum.IntEnum):  
  3. ...     AIR = 6  
  4. ...     PRO = 7  
  5. ...  
  6. >>> class Android(enum.IntEnum):  
  7. ...     MARSHMALLOW = 6  
  8. ...     NOUGAT = 7  
  9. ...  
  10. >>> Mac.AIR == Android.MARSHMALLOW  
  11. True  
透過繼承來組合出不同的 default enum (e.g. StrEnum)
我們可以透過繼承來達到前面 IntEnum 的效果,例如說要製作 StrEnum
  1. >>> import enum  
  2. >>> class StrEnum(str, enum.Enum):  
  3. ...     pass  
  4. ...  
  5. >>> class Browser(StrEnum):  
  6. ...     FIREFOX = 'firefox'  
  7. ...     CHROME = 'chrome'  
  8. ...  
  9. >>> Browser.FIREFOX == 'firefox'  
  10. True  
  11. >>> Browser.CHROME == 'chromium'  
  12. False  
透過 IntFlag 來進行 bitwise 操作:
如果是 IntFlag,執行 bitwise 操作 (&, |, ^, ~),回傳結果還會是 IntFlag 成員。如果是其他操作則會回傳 int:
  1. >>> class Permission(enum.IntFlag):  
  2. ...     R = 4  
  3. ...     W = 2  
  4. ...     X = 1  
  5. ...  
  6. >>> Permission.R | Permission.W  
  7. <Permission.R|W: 6>  
  8. >>> Permission.R | Permission.X  
  9. <Permission.R|X: 5>  
  10. >>> Permission.R + Permission.X  
  11. 5  
  12. >>> RW = Permission.R | Permission.W  
  13. >>> Permission.R in RW  
  14. True  
快速的創造 enum class
  1. >>> import enum  
  2. >>> Animal = enum.Enum('Animal''CAT DOG PANDA')  
  3. >>> Animal  
  4. <enum 'Animal'>  
  5. >>> Animal.CAT  
  6. <Animal.CAT: 1>  
  7. >>> Animal.DOG  
  8. <Animal.DOG: 2>  
  9. >>> Animal.PANDA  
  10. <Animal.PANDA: 3>  
  11. >>>  


沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...