XiWind 西風之劍
HomeTechProContactGitHub
  • About
  • Git
    • Windows Terminal、PowerShell 安裝
    • Git 開始使用
    • Branch 入門
    • 合併多個 Commit , 編輯
    • 額外功能
  • deep learning
    • Dilated Convolution
  • Python
    • GIL 【全域直譯器鎖】
    • PyPy 【JIT 編譯器】
    • Decorator 【修飾器】
      • Class Decorators
  • Python library
    • abc 【抽象 Class】
      • ABC, ABCMeta
      • __abstractmethods__, get_cache_token, update_abstractmethods
    • dataclasses 【數據 Class】
      • make_dataclass(), replace(), is_dataclass(), __post_init__
    • enum 【列舉 Class】
      • Flag, auto(), unique, verify()
      • 範例
    • concurrent.futures 【執行緒、程序】
      • Future, Module Functions
    • queue 【佇列、同步】
      • full(), empty(), qsize(), join(), task_done()
    • functools 【可調用物件】
      • ordering、wrapper、partial
      • Overloading
    • heapq 【堆積佇列】
      • heapify(), merge(), nlargest(), nsmallest()
    • time 【時間】
      • time(), monotonic(), perf_counter()...
      • sleep(), 範例...
    • logging 【日誌】
Powered by GitBook
On this page
  • 簡介
  • What is Enum?
  • How to Use Enum?
  • Why Use Enum?
  • When to Use Enum?
  • Conclusion
  • Enumeration data
  • Enum members, values
  • 範例 – 用法
  • Enum
  • IntEnum
  • StrEnum
  • EnumType
  • 範例 – 衍生 Enumerations

Was this helpful?

  1. Python library

enum 【列舉 Class】

Previousmake_dataclass(), replace(), is_dataclass(), __post_init__NextFlag, auto(), unique, verify()

Last updated 1 year ago

Was this helpful?

簡介


What is Enum?

Python 中的 enum module 是 standard library 的一部分,並提供對建立 enumerations 的支援,枚舉是綁定到唯一常數值的一組符號名稱(成員)。

Enum 是 Enumeration 的縮寫,是 Python 中的一個 class,用於建立 enumerations;是一組綁定到唯一值的符號名稱。每個 enumeration member 都有一個 name 和一個 value。 enum module 定義了 5 個 enumeration classes,可用來建立唯一的 names 和 values sets:Enum、IntEnum、Flag 和 IntFlag。

Enumeration 的 members 可以透過這些符號名稱進行比較,使程式碼更具可讀性和可維護性。

How to Use Enum?

Enumerations 是 immutable (不可變的),即它們不能更改。 一旦它們被建立,它們就保持不變。 Enumeration 是一組值的符號名稱。 Enumerations 是 iterable,可以使用迴圈來遍歷它們。

要定義 enumeration,可以透過 2 種方式:

  1. 繼承 Enum Class。

  2. 將名稱 sequence 傳遞給 Enum() 函數。(函數式 API,語法類似 )

PYTHON
from enum import Enum

# Method 1
class Color(Enum):
    RED = 1    # Enum member: RED
    GREEN = 2  # Enum member: GREEN
    BLUE = 3   # Enum member: BLUE

print(Color.RED)        # Output: Color.RED
print(Color.RED.name)   # Output: RED
print(Color.RED.value)  # Output: 1

# Method 2
Animal = Enum('Animal', 'CAT DOG BIRD')

print(Animal.CAT)        # Output: Animal.CAT
print(Animal.CAT.name)   # Output: CAT
print(Animal.CAT.value)  # Output: 1

for i in Animal:
    print(i)
'''
Output: 
Animal.CAT
Animal.DOG
Animal.BIRD
'''

您可能使用 1、2 和 3, 來表示任務的狀態:"正在進行"、"已完成"和"未開始"。

現在,您可以在程式碼中,使用 TaskStatus.IN_PROGRESS、TaskStatus.COMPLETED 和TaskStatus.NOT_STARTED,它們比原始數字更容易理解。

from enum import Enum

class TaskStatus(Enum):
    IN_PROGRESS = 1
    COMPLETED = 2
    NOT_STARTED = 3

Enumerations 是 Class,但它們通常用於建立唯一的常數集合 (建立實例),並且通常沒有方法,儘管包含方法是完全有效的。

對於大多數新程式碼,強烈建議使用 Enum 和 Flag。

因為 IntEnum 和 IntFlag 破壞了 enumeration 的一些語義承諾 (透過與整數進行比較,與其他不相關 enumerations 的傳遞性)。 IntEnum 和 IntFlag 應當僅在 Enum 和 Flag 不起作用的情況下使用。 例如:當整數常數被替換為 enumerations 時,或者為了與其他系統進行 interoperability 操作時。

Why Use Enum?

Enums 用於理解的術語 (terms) 表達的特定概念,並且還提供一系列功能,使它們比簡單的常數和 String 更強大且更易於維護。

如果使用 String 容易出現錯別字,如果不查看文檔或實現,就無法立即清楚有效的 Strings 是什麼,並且 IDE 中沒有自動完成支持。

透過定義 enum Class,您可以清楚地了解可以應用了哪些類型,並且更難犯錯誤。 您可以獲得 IDE 中的自動完成等好處,您不會拼錯 string,並且將來可以輕鬆新增或更改 enum Class。

使用 enumerations 的主要好處包括:

  1. 提高代碼可讀性和可維護性:Enums 允許開發人員使用命名值,而不是容易混淆或不清楚的數字或 String,從而提高了可讀性。

  2. 安全或防止錯誤:使用 enums,可以減少因為傳遞無效參數而導致的錯誤。如果你定義了一個期望使用枚舉的函數或方法,那麼它只能接收在枚舉中定義的值。

  3. Enumeration Iteration:Enum members 可以使用循環進行 iterated。 這允許更動態地處理 enum 值並且可以簡化代碼。

  4. 豐富的 Comparisons:Enum members 可以透過這些符號運算子進行比較,還可以進行 sorted 和 hashed。

在較小、較簡單的程序中這些好處可能不會立即顯現出來,但在較大、較複雜的應用程序中它們變得非常重要,並且通常被認為是一種良好的做法。

Python vs. C/C++ enumerations。

在 C/C++ 中,enumerations 是一種創建新類型的方法,它由一組命名的整數組成,enumeration 本身是整數類型。 在 Python 中,enumeration 的每個成員本身就是一個不同的值,而不僅僅是整數的別名。

When to Use Enum?

當您想要將一組相關的值組合在一起,並以一致的方式引用時,Enums 特別有用。例如:

  • State machine 中的狀態。

  • GUI 或 Web 應用程式的下拉式選單中的選項。

  • Categories, types or labels。 (例如: 產品類別)

  • Status codes or error codes。(例如: 錯誤和異常處理)

  • Handling Configuration Settings。

Conclusion

Python 中的 enum module 是創建 enumerable 常數的強大工具。透過使用 enums,開發人員可以編寫更易於閱讀、維護且不易出錯的程式碼。當處理一組代表某種狀態、類型或類別的預定義值時,它特別有用。

Enumeration data


Enumeration data: Enumeration 資料、enumerated 類型或 enum 是一種資料類型。 這是一個簡單的enumeration 範例:

PYTHON
from enum import Enum

class Color(Enum):
    RED = 1
    BLUE = 2
    GREEN = 3

print(Color.RED.name)   # Output: "RED"
print(Color.RED.value)  # Output: "1"

enumeration: Color enumeration members: RED, BLUE, GREEN 成員的名稱按照慣例為大寫,因為它們被視為常數。每個 enumeration member 都有兩個重要的屬性:name 和 value。 name 屬性給出 member name (string),value 屬性給出成員的值。

Enum members, values


有兩個同名的 enum members 是無效的。但是,兩個 enum members 允許具有相同的值。 給定兩個具有相同值的 members A 和 B(並且 A 首先定義),member B 是 A 的別名。

PYTHON
import enum

class Shape(enum.Enum):
    DIAMOND = 1
    SQUARE = 2
    CIRCLE = 3
    ALIAS_FOR_SQUARE = 2

print(Shape.SQUARE)            # Output: Shape.SQUARE
print(Shape.ALIAS_FOR_SQUARE)  # Output: Shape.SQUARE
print(Shape(2))                # Output: Shape.SQUARE

class Shape(enum.Enum):
    SQUARE = 2
    SQUARE = 3

# Output: 
# TypeError: 'SQUARE' already defined as 2

範例 – 用法


  1. 如果需要根據使用者的輸入訪問 Enum member 或其值,可以使用 Enum.member 來獲取該 member,或使用 Enum(value) 透過其值來獲取 Enum member。

  2. Enumeration 值被 repr() 解析為 <enum 'EnumName'>.<member_name>,而不是它們的值。

  3. Enum members 是 hashable,這意味著它們可以在需要 hashable 物件的任何 context 中使用。 這包括作為 dictionaries 中的 keys 和 Sets 中的元素,它們也是 immutable。

PYTHON
from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
    YELLOW = 4

# Accessing value of Enum member
print(Color.RED.value)  # Output: 1
print(Color.RED.name)   # Output: RED

# Accessing Enum member based on its value
print(Color(1))         # Output: Color.RED

# Accessing Enum member
print(Color.RED)        # Output: Color.RED
print(Color['RED'])     # Output: Color.RED

# =========================================================
print(repr(Color.RED))       # Output: <Color.RED: 1>
print(list(Color))           # Output: [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]
print(list(reversed(Color))) # Output: [<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>]
print(dir(Color))            # Output: ['BLUE', 'GREEN', 'RED', '__class__', '__doc__', '__members__', '__module__']
print(len(Color))            # Output: 3

print(type(Color))           # <class 'enum.EnumType'>
print(type(Color.RED))       # <enum 'Color'>
print(Color.RED in Color)    # Output: True
print(isinstance(Color.GREEN, Color)) # Output: True

# =========================================================
print(Color.RED is Color.BLUE)        # Output: False
print(Color.RED is not Color.BLUE)    # Output: True

print(Color.RED == Color.BLUE)        # Output: False
print(Color.RED != Color.BLUE)        # Output: True

# Enum members are not integers 
print(Color.RED == 1)                 # Output: False
#print(Color.RED < Color.BLUE)    
#print(Color.RED <= Color.BLUE) 

# =========================================================
# Iterating Enum
for i in Color:
    print(i)
'''
Color.RED
Color.GREEN
Color.BLUE
Color.YELLOW
'''

for name, member in Color.__members__.items():
    print(name, member)
'''
RED Color.RED
GREEN Color.GREEN
BLUE Color.BLUE
YELLOW Color.YELLOW
'''

# Used for detailed programmatic access
print([name for name, member in Color.__members__.items() if member.name != None])
# Output: ['RED', 'GREEN', 'BLUE', 'YELLOW']
'''
names = []
for name, member in Color.__members__.items():
    if member.name is not None:
        names.append(name)
'''

# =========================================================
# Enumeration members are hashable
# Use Enum members as dictionary keys
color_dict = {
    Color.RED: 'It symbolizes love and anger.',
    Color.GREEN: 'It symbolizes nature and tranquility.',
    Color.BLUE: 'It symbolizes sea and sky.',}
print(color_dict[Color.RED])     # Output: 'It symbolizes love and anger.'

# Use Enum members in sets
color_set = {Color.RED, Color.BLUE}
print(Color.GREEN in color_set)  # Output: False
print(Color.RED in color_set)    # Output: True

Enum


Enum 是 enum enumerations 的 Base Class。

EnumType 負責在其他 enum Class 上設置正確的方法,包含: name, value, _generate_next_value_, __str__ 方法...。

IntEnum


IntEnum 與 Enum 的用法大致相同,但它是 Enum 的 Subclass,且 enumeration 值是 int 的實例。

本質上,IntEnum members 可以參與所有 int 的 operations。如果對 IntEnum members 執行任何整數運算,則結果值將失去 enumeration 狀態。

PYTHON
from enum import IntEnum

class Number(IntEnum):
    ONE = 1
    TWO = 2
    THREE = 3

print(Number.THREE.value)       # Output: 1
print(Number.ONE + Number.TWO)  # Output: 3
print(Number.THREE + 5)         # Output: 8

# Loses its enumeration status
print(type(Number.THREE))     # Output: <enum 'Number'>
print(type(Number.THREE + 5)) # Output: <class 'int'>

StrEnum


StrEnum 與 Enum 的用法大致相同,但它是 Enum 的 Subclass,且 enumeration 值是 str 的實例。

本質上,IntEnum members 可以參與所有 str 的 operations。如果對 StrEnum members 執行任何字串運算,則結果值將失去 enumeration 狀態。

PYTHON
from enum import StrEnum

class Number(StrEnum):
    ONE = "ONE"
    TWO = "TWO"
    THREE = "THREE"

print(Number.ONE.value) # Output: "ONE"

print(type(Number.TWO)) # Output: <enum 'Number'>
print(type(Number.TWO + "TWO"))        # Output: <class 'str'>
print(type(Number.TWO + Number.THREE)) # Output: <class 'str'>

EnumType


EnumType 是 enum enumerations 的 Metaclass。 可以對 EnumType 進行Subclassing。

EnumType 負責在 enum 上設置正確的方法,包含: __call__, __repr__、__str__、__format__, __reduce__, __len__, __iter__ 方法...。

範例 – 衍生 Enumerations


透過擴展,不同類型的 IntEnum 也可以相互比較。但是,IntEnum 仍然無法與標準 Enum Enumerations 進行比較。

IntEnum 值的行為,也可以類似於整數。

PYTHON
from enum import IntEnum, Enum

class Shape(IntEnum):
    CIRCLE = 1
    SQUARE = 2

class Request(IntEnum):
    POST = 1
    GET = 2

print(Shape.CIRCLE == 1)             # Output: True
print(Shape.CIRCLE == Request.POST)  # Output: True

# =========================================================
class Color(Enum):
    RED = 1
    GREEN = 2
    
print(Shape.CIRCLE == Color.RED)     # Output: False

# =========================================================
# IntEnum To int
print(int(Shape.CIRCLE))                # Output: 1
# IntEnum To index
print(['a', 'b', 'c'][Shape.CIRCLE])    # Output: "b"
# IntEnum To len()
print([i for i in range(Shape.SQUARE)]) # Output: [0, 1]
collections.namedtuple
Page cover image