Výčtový typ

Výčtový typ (Enum) slouží k výčtu nějakého konečného počtu hodnot. Například názvy dnů v týdnu, výčet barev, typů platby na nějakém platebním portálu atp. Python podporuje Enum až od verze 3.4, takže tato kapitola se Pythonu 2.7 netýká.

Enum

Výčtový typ se vytváří děděním z enum.Enum, tj. z třídy Enum z modulu enum. Moduly budou popsány v jedné z dalších kapitol. Prozatím vám stačí vědět, že musíte Enum importovat pomocí řádky from enum import Enum.

from enum import Enum

class Barvy(Enum):
     red = "Cervena"
     blue = "#0000FF"
     black = 0

red, blue a black v příkladu jsou jména, kterým jsou přiřazeny (za rovnítkem) nějaké hodnoty.

Jak vidíte v příkladu, hodnota může být různého typu. Použití různých typů není ale obvykle dobrý nápad a hodnota výčtového typu vás ani většinou nezajímá. Rozumější příklad může vypadat takto:

from enum import Enum

class DenTydnu(Enum):
    po = 1
    ut = 2
    st = 3
    ct = 5
    pa = 6
    so = 7
    ne = 8

Výčtový typ není lecjaká obyčejná třída. Má několik speciálních vlastností.

Třída výčtového typu je iterovatelná:

>>> list(DenTydnu)
[<DenTydnu.po: 1>, <DenTydnu.ut: 2>, <DenTydnu.st: 3>, <DenTydnu.ct: 5>, <DenTydnu.pa: 6>, <DenTydnu.so: 7>, <DenTydnu.ne: 8>]

Členy výčtového typu mají jen jednu instanci (můžete se spolehnout na operátor is):

>>> DenTydnu.po = 100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.4/enum.py", line 292, in __setattr__
    raise AttributeError('Cannot reassign members.')
AttributeError: Cannot reassign members.

Člen výčtového typu je potomkem svého výčtového typu:

>>> isinstance(DenTydnu.po, DenTydnu)
True

Člen výčtového typu je třída, která má atributy name a value.
Člen výčtového typu se nerovná své hodnotě!

DenTydnu.po == 1
False
>>> DenTydnu.po.value == 1
True
>>> DenTydnu.po.name
'po'

Z toho taky plyne, že výčtové typy můžete porovnávat na rovnost a nerovnost, ale ne na "větší" a "menší".

>>> DenTydnu.po == DenTydnu.ut
False
>>> DenTydnu.po > DenTydnu.ut
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: DenTydnu() > DenTydnu()

Členové dvou výčtových typů se sobě nerovnají, ikdyž mají stejnou hodnotu:

class Mesic(Enum):
    le = 1
    un = 2
    br = 3
    du = 4
    ...
>>> Mesic.le == DenTydnu.po
False
>>> Mesic.le.value == DenTydnu.po.value
True

IntEnum

Výčtový typ může také dědit z enum.IntEnum. V takovém případě jsou členové výčtového typu také potomky int, tj. můžete s nimi zacházet jako s čísly.

from enum import IntEnum

class DenTydnu(IntEnum):
    po = 1
    ut = 2
    st = 3
    ct = 5
    pa = 6
    so = 7
    ne = 8

class Mesic(IntEnum):
    le = 1
    un = 2
    br = 3
    du = 4
    ...
>>> DenTydnu.po < DenTydnu.ut
True
>>> DenTydnu.po == Mesic.le
True
>>> DenTydnu.po == 1
True
>>> den = DenTydnu.ut
>>> print(["Pondeli","Uteri","Streda"][den-1])
Uteri
>>> list(DenTydnu)
[<DenTydnu.po: 1>, <DenTydnu.ut: 2>, <DenTydnu.st: 3>, <DenTydnu.ct: 5>, <DenTydnu.pa: 6>, <DenTydnu.so: 7>, <DenTydnu.ne: 8>]
>>> DenTydnu.po.value
1
>>> DenTydnu.po.name
'po'

Je doporučováno používat Enum spíše než IntEnum, právě kvůli tomu, že se IntEnum chová spíše jako číslo než jako Enum (můžete ho porovnávat s jiným číslem nebo s jiným IntEnum členem, na nerovnost). Většinou je špatně, že se pondělí rovná lednu …

Komentář Hlášení chyby
Created: 30.8.2015
Last updated: 30.8.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..