นากมิ้นต์ต้นฉบับติดป้ายหมายเลขเรียงแถวบนโต๊ะครีม โดยเครื่องปั๊มเลขสีอำพันพิมพ์เลขถัดไปให้อัตโนมัติ

Python enum.auto: ให้เลขสมาชิกเอง ไม่ต้องไล่พิมพ์เอง

น้องกายEngineering

เวลาทำสถานะงานหรือรหัสเหตุผลในโค้ด ผมเคยพิมพ์ 1, 2, 3 เองแล้วลืมเลื่อนเลขตอนแทรกค่ากลางทางครับ enum.auto() บอก Enum ให้เลือกค่าถัดไปเอง ตามลำดับที่ประกาศในคลาส

WHY: ลดงานซ้ำและลดบั๊กเลขชน

auto ใช้กับ Enum และ IntEnum ได้ ค่าเริ่มต้นของ IntEnum จะเริ่มที่ 1 แล้วบวกทีละ 1 ตามเอกสาร stdlib ถ้าต้องการฐานอื่น กำหนดค่าแรกเองแล้วปล่อย auto() ต่อท้ายได้

import unittest
from enum import Enum, IntEnum, auto


class TicketStatus(IntEnum):
    OPEN = auto()
    IN_PROGRESS = auto()
    DONE = auto()


class Priority(Enum):
    LOW = auto()
    MEDIUM = auto()
    HIGH = auto()


class EnumAutoTests(unittest.TestCase):
    def test_intenum_starts_at_one(self):
        self.assertEqual(list(TicketStatus), [
            TicketStatus.OPEN,
            TicketStatus.IN_PROGRESS,
            TicketStatus.DONE,
        ])
        self.assertEqual(TicketStatus.OPEN, 1)
        self.assertEqual(TicketStatus.DONE, 3)

    def test_enum_auto_unique_values(self):
        values = [member.value for member in Priority]
        self.assertEqual(len(values), len(set(values)))
        self.assertEqual(Priority.LOW.name, "LOW")


if __name__ == "__main__":
    unittest.main()

ข้อควรระวังตอนแทรกสมาชิก

ถ้าแทรก BLOCKED = auto() ระหว่าง OPEN กับ IN_PROGRESS ค่าตัวเลขของสมาชิกด้านหลังจะเลื่อนทั้งหมด ระบบที่เก็บเลขลงฐานข้อมูลอยู่แล้วจะอ่านเพี้ยนได้ ทางปลอดภัยคือกำหนดค่าคงที่ให้สมาชิกที่ถูก serialize แล้ว หรือใช้ชื่อสตริงเป็นค่าแทนตัวเลข

Recap

  • ใช้ auto() เมื่ออยากไล่ค่าตามลำดับประกาศ
  • IntEnum เริ่มที่ 1 โดยค่าเริ่มต้นของ stdlib
  • อย่าแทรกสมาชิกกลางทางถ้าเลขถูกเก็บนอกโปรเซสแล้ว