Skip to content

Pythonning enum moduli haqida

Enum Pythonda nomlangan o'zgarmas qiymatlar to'plamini ifodalash uchun ma'lumot turi. Enum nomi Enumeration so'zining qisqartmasidan olingan. Enum kodni yanada o'qilishi oson va tushunarli qiladi, chunki oddiy qiymatlar o'rniga aniq manoga ega nomlar bilan ishlash imkonini beradi.

Enum turini e'lon qilish.

Pythonda enum moduli bor, unda Enum deb nomlangan class mavjud va bu class orqali enumeration (enum) turini e'lon qilish mumkin. Unda amaliyotga o'tsak ham bo'ladi. Tasavur qiling siz foydalanuvchilarni ro'yxatga olish tizimini yozyapsiz bu tizimda 3 ta foydalanuvchi turi ya'ni rollari mavjud, bular user, admin va manager bular dinamik emas o'zgarmas bo'ladi. Quyida Enum bilan quyidagicha e'lon qilishimiz mumkin:


enums.py
1
2
3
4
5
6
7
from enum import Enum

class UserRoles(Enum):
    ADMIN = 1
    USER = 2
    MANAGER = 3
print(list(UserRoles))

Natija:

[<UserRoles.ADMIN: 1>, <UserRoles.USER: 2>, <UserRoles.MANAGER: 3>]

Info

Enumda atributlar member deb nomlanadi.

Enum iterable tur hisoblanadi ya'ni sikl bilan qiymatlarni yurib chiqish mumkin. Shuning uchun yuqorida list turiga casting qilinganida har bir atribut UserRoles turida ro'yxat elementlari sifatida chop qilindi. Yana bir bilishimiz kerak bo'lgan ma'lumot Enum atributlari har biri alohida tur obyekti hisoblanadi. Quyida e'lon qilingan o'zgarmaslarga qanday murojaat qilishni ko'ramiz.


enums.py
1
2
3
4
5
6
7
8
from enum import Enum

class UserRoles(Enum):
    ADMIN = 1
    USER = 2
    MANAGER = 3

print(UserRoles.ADMIN)

Natija:

UserRoles.ADMIN

Bu yerdagi natija o'zgarmas qiymati emas. Bu biz yozgan tur nomi va murojaat qilingan atribut nomi. Yuqorida aytganimizdek har bir atribut alohida tur obyekti hisoblanadi, obyekt atributlariga esa . bilan murojaat qilinadi. Enum turidagi obyektlarda ikkita method bor bular name va value. name atribut nomini, value esa atribut qiymatini qaytaradi.


enums.py
1
2
3
4
5
6
7
8
9
from enum import Enum

class UserRoles(Enum):
    ADMIN = 1
    USER = 2
    MANAGER = 3

print(UserRoles.ADMIN.name)
print(UserRoles.ADMIN.value)

Natija:

ADMIN
1

Enum atributlarini o'zgartirib bo'lmaydi chunki ular o'zgarmas(immutable) hisoblanadi.


enums.py
from enum import Enum

class UserRoles(Enum):
    ADMIN = 1
    USER = 2
    MANAGER = 3

UserRoles.ADMIN = 0

print(list(UserRoles))

Natija:

AttributeError: Cannot reassign members.

Ko'rib turganingizdek biz atributga yangi qiymatni biriktirmoqchi bo'lganimizda, yuqoridagi xatolik sodir bo'ldi. Shu yo'l bilan o'zgarmaslarni himoya qilib, kodni ishonchliligi ta'minlanadi.

Agar enum turi uchun atribut qiymatlarini dinamik ko'rinishda bermoqchi bo'lsak, bu quyidagicha amalga oshiriladi:


enums.py
1
2
3
4
5
6
7
8
from enum import Enum, auto

class UserRoles(Enum):
    ADMIN = auto()
    USER = auto()
    MANAGER = auto()

print(list(UserRoles))

Natija:

[<UserRoles.ADMIN: 1>, <UserRoles.USER: 2>, <UserRoles.MANAGER: 3>]

Bu yerda Python 1,2,3 ketma-ketlikda qiymat(value) qo'shib beradi.

Enum haqida yaxshiroq tushinish uchun quyida real loyihaga yaqinroq misol ko'ramiz, shunda o'zi nima uchun kerakligi yana ham aniqroq bo'ladi.


enums.py
from enum import Enum

class OrderStatus(Enum):
    NEW = "new"
    PAID = "paid"
    CANCELLED = "cancelled"

def process(order_status):
    if order_status == OrderStatus.NEW:
        print("Yangi buyurtma")
    if order_status ==  OrderStatus.PAID:
        print("To'langan")
    if order_status == OrderStatus.CANCELLED:
        print("Bekor qilingan")

process(OrderStatus.NEW)

Natija:

Yangi buyurtma

Bu misolda internet do'konning buyurtmalar holatini(status) saqlash ko'rsatilgan. Buyurtma (order) uchun mumkin bo'lgan holatlarni oldindan belgilab qo'yganmiz, bu yerda holatlar aniq belgilab qo'yilgan, boshqa qiymatlar berib bo'lmaydi. process funksiyasi berilgan order_statusni if shart blokiga ga uzatadi, u yerda qiymat tekshirilib mos kelgan if bloki ishga tushadi.

Enum turida e'lon qilingan o'zgarmaslar bilan ishlaganda turiga ham e'tibor berish kerak. Yuqoridagi OrderStatus misolida ko'rsak atributlar str turida e'lon qilingan lekin uni if OrderStatus.NEW == 'new': ko'rinishida tekshira olmaymiz chunki 'new' bu str turida OrderStatus.NEW esa OrderStatus turida. Bunday holatlarda quyidagicha type casting qilish kerak bo'ladi:

enums.py
from enum import Enum

class OrderStatus(Enum):
    NEW = "new"
    PAID = "paid"
    CANCELLED = "cancelled"

def process(order_status):
    if order_status == OrderStatus.NEW:
        print("Yangi buyurtma")
    if order_status ==  OrderStatus.PAID:
        print("To'langan")
    if order_status == OrderStatus.CANCELLED:
        print("Bekor qilingan")

process(OrderStatus('new'))

Keling endi atributlarda e'lon qilinmagan qiymat berilsa nima sodir bo'lishini ko'ramiz:

enums.py
from enum import Enum

class OrderStatus(Enum):
    NEW = "new"
    PAID = "paid"
    CANCELLED = "cancelled"

def process(order_status):
    if order_status == OrderStatus.NEW:
        print("Yangi buyurtma")
    if order_status ==  OrderStatus.PAID:
        print("To'langan")
    if order_status == OrderStatus.CANCELLED:
        print("Bekor qilingan")

process(OrderStatus('old'))

Natija:

ValueError: 'old' is not a valid OrderStatus

Qisqa qilib aytganda Enum noto'g'ri qiymatlar berilishini oldini oladi. Enum faqat o'zgarmaslarni saqlash uchun emas balki toza va kengayish oson bo'lgan kod yozishga yordam beradi.

Bu kichik qo'llanma orqali sizga Enum haqida ozroq bo'lsa ham ma'lumot ulasha olgan bo'lsam xursand bo'laman. Agar sizda savol, taklif yoki tanqidlar bo'lsa shu manzillarda kutaman: @Py_uz, farrux [at] elomonov.uz.