โมดูล enum ให้ Enumeration Type ใน Python (Python 3.4+) Enum มี Name และ Value เข้าถึงได้ทั้ง 2 แบบ
import enum
การสร้าง Enum พื้นฐาน
import enum
class Rainbow(enum.Enum):
VIOLET = 1
INDIGO = 2
BLUE = 3
GREEN = 4
YELLOW = 5
ORANGE = 6
RED = 7
# เข้าถึง
print(Rainbow(3)) # Rainbow.BLUE (จาก Value)
print(Rainbow['ORANGE']) # Rainbow.ORANGE (จาก Name)
print(Rainbow.ORANGE.value) # 6 (Value)
print(Rainbow.ORANGE.name) # 'ORANGE' (Name)
# Iterate
for color in Rainbow:
print(f"{color.name} = {color.value}")
ผลลัพธ์
Rainbow.BLUE Rainbow.ORANGE 6 ORANGE VIOLET = 1 INDIGO = 2 BLUE = 3 GREEN = 4 YELLOW = 5 ORANGE = 6 RED = 7
คุณสมบัติสำคัญ
- Immutable: ไม่สามารถเปลี่ยน Value ได้หลังสร้าง
- Unique Values: Default ต้องไม่ซ้ำ (ใช้
@enum.uniqueบังคับ) - Comparable: เทียบได้เฉพาะ Enum เดียวกัน (
Rainbow.RED == Rainbow.RED) - Iterable: วนลูปได้ตามลำดับ定义
- Serializable: JSON Encoder รองรับ (Python 3.11+)
Enum Types เฉพาะ
IntEnum - เปรียบเทียบกับ Int ได้
class Priority(enum.IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
print(Priority.HIGH > Priority.LOW) # True
print(Priority.HIGH + 10) # 13 (เป็น Int ได้)
print(isinstance(Priority.HIGH, int)) # True
StrEnum - เป็น String ได้ (3.11+)
class Color(enum.StrEnum):
RED = 'red'
GREEN = 'green'
print(Color.RED == 'red') # True
Flag / IntFlag - Bitwise Operations
class Permission(enum.Flag):
READ = 1
WRITE = 2
EXECUTE = 4
p = Permission.READ | Permission.WRITE # Permission.READ | Permission.WRITE
print(p & Permission.READ) # Permission.READ
print(bool(p & Permission.EXECUTE)) # False
Auto Values
class AutoEnum(enum.Enum):
A = enum.auto()
B = enum.auto()
C = enum.auto()
# A=1, B=2, C=3
Methods และ Properties เพิ่มเติม
__members__- OrderedDict ของ Name -> Member (รวม Aliases)cls(name)- Lookup จาก Namecls(value)- Lookup จาก Value
Best Practices
- ใช้
@enum.uniqueป้องกัน Duplicate Values - ใช้
IntEnumเมื่อต้องเปรียบเทียบกับ Integer - ใช้
Flagสำหรับ Bitmask Permissions - Enum Members ควรเป็น UPPER_CASE
- Docstring ให้ Class และ Members
ตัวอย่าง: HTTP Status Codes
class HTTPStatus(enum.IntEnum):
OK = 200
CREATED = 201
BAD_REQUEST = 400
UNAUTHORIZED = 401
NOT_FOUND = 404
INTERNAL_SERVER_ERROR = 500
def handle_response(status: HTTPStatus):
if status >= HTTPStatus.BAD_REQUEST:
print(f"Error: {status.name} ({status.value})")
else:
print(f"Success: {status.name}")
handle_response(HTTPStatus.OK)
handle_response(404) # Int -> Enum Auto-convert (IntEnum)