Konsep Enum — class khusus yang nilainya terbatas dan bernama — sudah kita pelajari tuntas pada Chapter Enum di Section Advanced Data Modeling. Chapter ini mengambil sudut pandang berbeda: bagaimana module enum dipakai sehari-hari di kode produksi. Kita akan meninjau isi module, iterasi anggota, lalu menerapkan tiga resep nyata: StrEnum, state machine, dan nilai konfigurasi.
Menjelajahi Isi Module dan unique() #
Kita mulai dengan meninjau apa yang disediakan module enum lewat satu contoh StatusPesanan:
from enum import Enum, unique
@unique
class StatusPesanan(Enum):
BARU = 1
DIPROSES = 2
DIKIRIM = 3
SELESAI = 4
print(list(StatusPesanan))
print(list(StatusPesanan.__members__))
print(StatusPesanan(2))
print(StatusPesanan.DIKIRIM.name, StatusPesanan.DIKIRIM.value)Output yang Dihasilkan:
[<StatusPesanan.BARU: 1>, <StatusPesanan.DIPROSES: 2>, <StatusPesanan.DIKIRIM: 3>, <StatusPesanan.SELESAI: 4>]
['BARU', 'DIPROSES', 'DIKIRIM', 'SELESAI']
StatusPesanan.DIPROSES
DIKIRIM 3Mari kita bedah kode di atas:
- Baris 4 (
@unique): decorator dari moduleenumyang menolak nilai ganda. Tanpaunique(), dua anggota boleh berbagi nilai dan pemetaan balik jadi membingungkan. - Baris 12 (
list(StatusPesanan)): mengiterasi class menghasilkan semua anggota dalam urutan definisi — berguna untuk mengisi pilihan dropdown. - Baris 13 (
__members__): dictionary pemetaan nama ke anggota;.keys()-nya memberi daftar nama sebagai string. - Baris 14 (
StatusPesanan(2)): pencarian balik dari nilai ke anggota — misalnya saat membaca angka dari database. - Baris 15 (
.namedan.value): tiap anggota membawa namanya ("DIKIRIM") dan nilainya (3) sebagai atribut terpisah.
Decorator unique() bekerja dengan menimbulkan exception saat class ternyata memuat nilai ganda:
from enum import Enum, unique
try:
@unique
class Kode(Enum):
A = 1
B = 1
except ValueError as e:
print(type(e).__name__, "-", e)Output yang Dihasilkan:
ValueError - duplicate values found in <enum 'Kode'>: B -> AGalat ini muncul saat import — artinya kesalahan ketik nilai tertangkap sebelum program sempat berjalan di produksi, bukan setelahnya.
StrEnum untuk Nilai String #
Sejak Python 3.11, module enum menyediakan class StrEnum yang anggotanya berperilaku sebagai str biasa:
from enum import StrEnum
class Peran(StrEnum):
ADMIN = "admin"
PENGGUNA = "user"
def tampilkan_peran(peran):
print(f"peran: {peran}")
tampilkan_peran(Peran.ADMIN)
print(Peran.ADMIN == "admin")Output yang Dihasilkan:
peran: admin
TrueAnggota StrEnum otomatis dikonversi ke string saat digabung dengan f-string, dan perbandingan langsung dengan string "admin" menghasilkan True. Resep ini ideal ketika sistem eksternal — template, JSON, database — mengharapkan teks, sementara kode internal kita tetap ingin keuntungan Enum bernama.
Resep: State Machine dengan Enum #
Status yang berpindah mengikuti aturan adalah kasus favorit Enum. Kita definisikan status beserta table transisinya, lalu function proses() menjalankan perpindahan:
from enum import Enum
class Status(Enum):
MENUNGGU = "menunggu"
DITERIMA = "diterima"
DITOLAK = "ditolak"
TRANSISI = {
(Status.MENUNGGU, "setuju"): Status.DITERIMA,
(Status.MENUNGGU, "tolak"): Status.DITOLAK,
}
def proses(status, aksi):
try:
return TRANSISI[(status, aksi)]
except KeyError:
return status
status = Status.MENUNGGU
status = proses(status, "setuju")
print(status)
status = proses(status, "setuju")
print(status)Output yang Dihasilkan:
Status.DITERIMA
Status.DITERIMADictionary TRANSISI menjadikan pasangan (status, aksi) sebagai key sehingga aturan bisnis terlihat sebagai data, bukan rantai if-elif. Function proses() kedua kalinya mengembalikan status yang sama karena pasangan (DITERIMA, "setuju") tidak terdaftar — state machine menolak perpindahan yang tidak sah tanpa crash.
Resep: Enum sebagai Key Konfigurasi #
Nilai Enum bersifat hashable dan bisa dipakai sebagai key dictionary. Pola ini menggantikan konstanta string yang rawan salah ketik:
from enum import Enum
class Lingkungan(Enum):
PENGEMBANGAN = "development"
STAGING = "staging"
PRODUKSI = "production"
CONFIG = {
Lingkungan.PENGEMBANGAN: {"debug": True, "port": 8000},
Lingkungan.PRODUKSI: {"debug": False, "port": 80},
}
lingkungan = Lingkungan.PENGEMBANGAN
print(CONFIG[lingkungan]["debug"])Output yang Dihasilkan:
TrueJika kita menulis Lingkungan.PRODUKSION (salah ketik), interpreter langsung menimbulkan AttributeError saat program dimuat — jauh lebih aman daripada key string "production" yang salah ketik dan senyap mengembalikan KeyError di jalur kode yang jarang diuji.
Dari peninjauan module, StrEnum, sampai dua resep produksi di atas, module enum membuktikan diri bukan sekadar cara memberi nama angka — melainkan fondasi untuk aturan bisnis yang ketat sejak program dimuat.