Како енумови у Питхон-у побољшавају читљивост кода

Enumi su popularan tip podataka koji se koristi u programskim jezicima kao što su C, C++ i Java. Oni značajno doprinose kreiranju koda koji je siguran u smislu tipova i znatno čitljiviji.

U programskom jeziku Python, podrška za enume nije bila uvek prisutna. Međutim, od verzije 3.4, Python sada pruža podršku za enume. Ovaj tekst služi kao vodič za kreiranje i korišćenje enuma, kao i za razumevanje njihove uloge u poboljšanju čitljivosti koda.

Šta su enumi i koja je njihova svrha?

Enumeracija, ili enum, predstavlja tip podataka definisan skupom jasno određenih vrednosti koje promenljiva može da preuzme. Ovaj skup vrednosti poznat je kao skup njegovih članova. Enumi omogućavaju precizno definisanje opsega mogućih vrednosti koje promenljiva može imati, što rezultira sigurnijim kodom i povećava njegovu čitljivost.

Važni termini koje treba znati

Pre nego što nastavimo sa detaljnijim razmatranjem enuma, neophodno je definisati nekoliko ključnih termina koje ćemo koristiti. To su članovi i vrednosti.

  • Članovi: Predstavljaju imenovane konstante koje zajedno čine skup vrednosti koje pripadaju enumeraciji. Na primer, lista „Dani“ može sadržati članove kao što su nedelja, ponedeljak, utorak itd.
  • Vrednosti: To su interne vrednosti koje se koriste za jedinstveno predstavljanje svakog člana enumeracije, omogućavajući poređenja. Na primer, u enumeraciji „Dani“, nedelja može imati vrednost 0, ponedeljak 1, utorak 2 i tako dalje.

U nastavku ćemo razmotriti kako enumi doprinose poboljšanju kvaliteta koda.

Kako enumi unapređuju vaš kod

Enumi značajno unapređuju kvalitet koda, čineći ga čitljivijim i manje podložnim greškama. U nastavku su navedeni neki od ključnih razloga zašto biste ih trebali koristiti:

  • Enumi vam omogućavaju da jasno definišete koje vrednosti se očekuju za datu promenljivu ili argument funkcije. Na taj način, olakšavate razumevanje namere koda, kako za vas, tako i za druge programere.
  • Enumi čine kod sam dokumentujućim. To znači da više nije neophodno dodavati opširne komentare ili dokumentaciju kako biste objasnili koje su moguće vrednosti argumenta funkcije, jer su one jasno definisane enumom.
  • Takođe, omogućavaju integrisanim razvojnim okruženjima (IDE) da efikasnije prepoznaju greške, npr. prilikom prosleđivanja nevažećih vrednosti i nude podršku za automatsko dovršavanje koda.
  • Kao rezultat svega navedenog, vaš kod postaje sigurniji u pogledu tipova i smanjuje se mogućnost pojave grešaka tokom izvršavanja.

U narednom delu teksta, detaljnije ćemo objasniti proces kreiranja enuma u programskom jeziku Python.

Kako kreirati enume u Python-u

Python ne podržava enume direktno u jezgru, već pruža `enum` modul u standardnoj biblioteci, koji ćemo koristiti u ovom vodiču. Postoje dva osnovna načina za kreiranje enumeracija u Python-u: korišćenjem klasa ili putem API funkcija. Oba metoda će biti detaljno objašnjena u ovom odeljku.

Preduslovi

Za praćenje ovog vodiča, neophodno je da imate instaliran Python 3.4 ili noviju verziju, koja dolazi sa `enum` modulom u standardnoj biblioteci. Ukoliko niste sigurni kako da instalirate Python, možete pronaći uputstva na internetu.

Takođe, poželjno je da imate osnovno znanje o Python-u, uključujući osnovne koncepte i naprednije, kao što su klase i nasleđivanje u okviru objektno orijentisanog programiranja.

#1. Metod korišćenja klasa

Prvi način za kreiranje enuma je korišćenjem klasa. Najpre, potrebno je importovati `Enum` klasu iz `enum` modula. Zatim, kreirate sopstveni enum definisanjem nove klase koja nasleđuje `Enum` klasu koju ste prethodno importovali.

from enum import Enum

class Direction(Enum):
    NORTH = 0
    EAST = 1
    SOUTH = 2
    WEST = 3

Možete dodeliti proizvoljne vrednosti članovima enuma. Na primer, umesto da dodelimo 0, 1, 2 i 3 našoj enumeraciji pravaca, možemo dodeliti vrednosti koje odgovaraju uglu u stepenima: 0, 90, 180 i 270.

from enum import Enum

class Direction(Enum):
    NORTH = 0
    EAST = 90
    SOUTH = 180
    WEST = 270

Alternativno, može se koristiti funkcija `range` za sažetiji način generisanja gornjeg primera. U nastavku je prikazan primer:

from enum import Enum

class Direction(Enum):
    NORTH, EAST, SOUTH, WEST = range(0, 360, 90)

U ovom slučaju, vrednosti generišemo koristeći funkciju `range`, pri čemu definišemo 0 kao početnu, 360 kao krajnju, i 90 kao vrednost za inkrementiranje. Vrednosti se dodeljuju članovima enuma slično kao prilikom raspakivanja torki. Dodatne informacije o raspakivanju torki možete pronaći u odgovarajućim vodičima.

Enum klase su apstraktne, što znači da se ne instanciraju direktno, već se direktno pristupa njihovim svojstvima koja predstavljaju članove enuma.

#2. Funkcionalni metod

Funkcionalni metod predstavlja alternativu metodu potklasiranja.

from enum import Enum

Direction = Enum("Direction", ["NORTH", "EAST", "SOUTH", "WEST"])

U prikazanom segmentu koda, kreirali smo enum pod nazivom `Direction`, koji sadrži četiri člana navedena kao drugi argument. Po defaultu, ovim članovima su dodeljene vrednosti počev od 1. Tako, sever ima vrednost 1, istok 2, i tako dalje. Ovo je specifičan slučaj, a ne indeksiranje počevši od nule, jer je 0 lažna vrednost. Stoga, da bi sve vrednosti bile tačne, numerisanje počinje od 1.

Alternativno, možete eksplicitno dodeliti vrednosti svojim članovima prosleđivanjem članova kao liste torki, gde svaka torka sadrži dva elementa: ime člana i njegovu odgovarajuću vrednost.

from enum import Enum

Direction = Enum(
    name = "Direction",
    values = [
        ("NORTH", "n"),
        ("EAST", "e"),
        ("SOUTH", "s"),
        ("WEST", "w"),
    ]
)

U navedenom primeru, koristili smo niske umesto celih brojeva prilikom dodeljivanja vrednosti članovima, što pokazuje da su niske validne vrednosti kao i celi brojevi.

Kako koristiti enume

U prethodnom delu objasnili smo kako se kreiraju enumi i kako se dodeljuju vrednosti članovima. U ovom odeljku ćemo se baviti pristupom članovima enuma, njihovom dodeljivanju i proveri jednakosti.

Kako pristupiti članovima

Postoji nekoliko načina za pristup članovima enuma, uključujući sintaksu tačke, zagrada i uglastih zagrada. U nastavku je prikazan primer:

from enum import Enum

# Kreiranje enuma
class Day(Enum):
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY = range(1, 8)

# Pristup članovima enuma
# 1. Koriscenjem sintakse tacke
print(Day.SUNDAY)

# 2. Koriscenjem uglastih zagrada
print(Day["MONDAY"])

# 3. Koriscenjem zagrada
print(Day(3))

Nakon pristupa članu enuma, možete ga sačuvati u promenljivu. Važno je zapamtiti da vam pristup članu daje referencu na sam objekat člana, a ne direktno njegovu vrednost ili ime. Ovo je bitno za naredne odeljke.

Pristup imenu i vrednosti

Kao što je prethodno navedeno, pristupom članu enuma kreirate referencu na sam objekat člana. Ako iz nekog razloga želite pristupiti imenu ili vrednosti objekta enuma, možete koristiti svojstva `name` i `value` na samom objektu.

print(Day.SUNDAY.name, Day.SUNDAY.value)

Provera jednakosti

Podsetimo se, dodeljivanje člana enumeracije promenljivoj kreira referencu na objekat člana te enumeracije. Dakle, da bismo proverili da li promenljiva ima određeni član enumeracije, koristimo `is` operator, kako bismo proverili da li član enumeracije i promenljiva pokazuju na isti objekat.

U nastavku je prikazan primer:

today = Day.WEDNESDAY

if today is Day.MONDAY:
    print("It's a Monday, :(")

if today is Day.WEDNESDAY:
    print("Happy Wednesday")

Alternativno, možete koristiti `==` operator. U superklasama klase `Enum`, operator `==` je omotač za `is` operator. Ovo se postiže preopterećenjem operatora. Detaljnije informacije o ovome možete pronaći u člancima koji opisuju magične metode. U svakom slučaju, u nastavku je prikazan primer koji umesto `is` koristi `==`.

today = Day.WEDNESDAY

if today == Day.MONDAY:
    print("It's a Monday, :(")

if today == Day.WEDNESDAY:
    print("Happy Wednesday")

Ponavljajući, poređenja enuma proveravaju identitet objekata, a ne njihove vrednosti.

Završne reči

Ovaj tekst je obuhvatio definiciju enuma i razloge njihove korisnosti. Takođe, objašnjene su različite metode za kreiranje enuma, korišćenjem potklasiranja `Enum` klase, kao i funkcionalnog API-ja.

Dodatno, razmotrili smo kako se koriste enumi, kako se pristupa njihovim vrednostima i kako se vrše poređenja. Za dodatne informacije, možete pogledati naš članak o TypeScript enumima.