enum — 열거형 지원

enum — 열거형 지원

버전 3.4에 추가됨.

이 페이지는 API 참조 정보를 담고 있어요. 튜토리얼 정보와 더 고급 주제 논의는 기본 튜토리얼, 고급 튜토리얼, Enum Cookbook을 참고하세요.

출처: Python 표준 라이브러리

본문

열거형(enumeration)은:

  • 고유한 값에 바인딩된 상징적 이름(멤버)들의 집합
  • 정의 순서대로 표준(즉, 별칭이 아닌) 멤버를 돌려주도록 반복할 수 있음
  • 호출 문법으로 값별로 멤버를 돌려줌
  • 인덱스 문법으로 이름별로 멤버를 돌려줌

열거형은 클래스 문법 또는 함수 호출 문법으로 만들 수 있어요.

>>> from enum import Enum

>>> # class syntax
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3

>>> # functional syntax
>>> Color = Enum('Color', [('RED', 1), ('GREEN', 2), ('BLUE', 3)])

클래스 문법으로 Enum을 만들 수 있어도, Enum은 일반 Python 클래스가 아니에요. Enum이 일반 클래스와 어떻게 다른지는 상세한 내용을 참고하세요.

용어 — 클래스 Color는 열거형(enumeration, 또는 enum)이에요. 속성 Color.RED, Color.GREEN 등은 열거형 멤버(멤버)이고 기능적으로 상수예요. 열거형 멤버는 이름과 값을 가져요(Color.RED의 이름은 RED, Color.BLUE의 값은 3 등).

모듈 내용

이름 설명
EnumType Enum과 그 하위 클래스의 타입.
Enum 열거형 상수를 만들기 위한 기본 클래스.
IntEnum int의 하위 클래스이기도 한 열거형 상수를 만들기 위한 기본 클래스.
StrEnum str의 하위 클래스이기도 한 열거형 상수를 만들기 위한 기본 클래스.
Flag 비트 연산으로 결합해도 Flag 멤버십을 잃지 않는 열거형 상수를 만들기 위한 기본 클래스.
IntFlag 비트 연산자로 결합해도 IntFlag 멤버십을 잃지 않는 열거형 상수를 만들기 위한 기본 클래스. IntFlag 멤버는 int의 하위 클래스이기도 함.
ReprEnum 혼합된 타입의 str()을 유지하기 위해 IntEnum, StrEnum, IntFlag가 사용함.
EnumCheck verify()와 함께 사용해 주어진 열거형이 다양한 제약을 만족하는지 보장하는 값 CONTINUOUS, NAMED_FLAGS, UNIQUE를 가진 열거형.
FlagBoundary 열거형에서 잘못된 값을 어떻게 다루는지 더 세밀하게 제어할 수 있게 하는 값 STRICT, CONFORM, EJECT, KEEP을 가진 열거형.
EnumDict EnumType을 서브클래싱할 때 사용하는 dict의 하위 클래스.
auto Enum 멤버에 대해 적절한 값으로 대체되는 인스턴스. StrEnum은 멤버 이름의 소문자 버전을 기본으로 하고, 다른 Enum은 기본적으로 1부터 증가.
@enum.property 멤버 이름과 충돌하지 않으면서 Enum 멤버가 속성을 가질 수 있게 함. valuename 속성이 이런 식으로 구현됨.
@unique 어떤 값에도 오직 하나의 이름만 바인딩되도록 보장하는 Enum 클래스 데코레이터.
@verify 열거형에 대해 사용자가 선택한 제약을 검사하는 Enum 클래스 데코레이터.
@member obj를 멤버로 만듦. 데코레이터로 쓸 수 있음.
@nonmember obj를 멤버로 만들지 않음. 데코레이터로 쓸 수 있음.
@global_enum enum의 str()repr()을 멤버가 클래스가 아니라 모듈에 속한 것처럼 표시하도록 수정하고, enum 멤버를 전역 네임스페이스로 내보냄.
show_flag_values() 플래그에 포함된 모든 2의 거듭제곱 정수 리스트를 돌려줌.
enum.bin() 내장 bin()과 같지만, 음수 값은 2의 보수로 표현되고 선두 비트가 항상 부호를 나타냄(0은 양수, 1은 음수).

버전 3.6에 추가됨: Flag, IntFlag, auto 버전 3.11에 추가됨: StrEnum, EnumCheck, ReprEnum, FlagBoundary, property, member, nonmember, global_enum, show_flag_values 버전 3.13에 추가됨: EnumDict

데이터 타입

class enum.EnumType

EnumType은 enum 열거형의 메타클래스예요. EnumType을 서브클래싱할 수 있어요 — 자세한 내용은 EnumType 서브클래싱을 참고하세요.

EnumType은 최종 enum에 올바른 __repr__(), __str__(), __format__(), __reduce__() 메서드를 설정하고, enum 멤버를 만들고, 중복을 적절히 처리하고, enum 클래스에 대한 반복을 제공하는 등의 역할을 담당해요.

버전 3.11에 추가됨: 3.11 이전에 EnumTypeEnumMeta라고 불렸으며, 여전히 별칭으로 사용 가능함.

call(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

이 메서드는 두 가지 방식으로 호출돼요.

기존 멤버 조회cls: 호출되는 enum 클래스, value: 조회할 값.

기존 enum이 멤버가 없다면, cls enum을 사용해 새 enum 만들기cls: 호출되는 enum 클래스, value: 만들 새 Enum의 이름, names: 새 Enum 멤버의 이름/값, module: 새 Enum이 만들어지는 모듈 이름, qualname: 모듈 안에서 이 Enum을 찾을 수 있는 실제 위치, type: 새 Enum용 믹스인 타입, start: Enum의 첫 정수 값(auto가 사용), boundary: 비트 연산의 범위 밖 값 처리 방법(Flag만).

contains(cls, member)

membercls에 속하면 True를 돌려줘요.

>>> some_var = Color.RED
>>> some_var in Color
True
>>> Color.RED.value in Color
True

버전 3.12에서 변경: Python 3.12 이전에는 포함 검사에 비-Enum 멤버가 쓰이면 TypeError가 발생했음.

dir(cls)

['__class__', '__doc__', '__members__', '__module__']cls의 멤버 이름들을 돌려줘요.

>>> dir(Color)
['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__']

getitem(cls, name)

cls에서 name과 일치하는 Enum 멤버를 돌려주거나, KeyError를 발생시켜요.

>>> Color['BLUE']
<Color.BLUE: 3>

iter(cls)

cls의 각 멤버를 정의 순서대로 돌려줘요.

>>> list(Color)
[<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]

len(cls)

cls의 멤버 수를 돌려줘요.

>>> len(Color)
3

members

모든 enum 이름을 그 멤버로 매핑하는 매핑을 돌려줘요(별칭 포함).

reversed(cls)

cls의 각 멤버를 역순 정의 순서로 돌려줘요.

>>> list(reversed(Color))
[<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>]

class enum.Enum

Enum은 모든 enum 열거형의 기본 클래스예요.

name

Enum 멤버를 정의하는 데 사용된 이름.

>>> Color.BLUE.name
'BLUE'

value

Enum 멤버에게 주어진 값.

>>> Color.RED.value
1

멤버의 값이며, __new__()에서 설정할 수 있어요.

Enum 멤버 값 — 멤버 값은 무엇이든 될 수 있어요: int, str 등. 정확한 값이 중요하지 않으면 auto 인스턴스를 쓸 수 있고 적절한 값이 선택돼요. 자세한 내용은 auto를 참고하세요. dict, list, 가변 dataclass 같은 가변/비해시 값도 쓸 수 있지만, 생성 중 enum의 가변/비해시 값 총 수에 상대적인 이차 성능 영향이 있어요.

name

멤버의 이름.

value

멤버의 값. __new__()에서 설정할 수 있어요.

order

더 이상 사용되지 않고, 하위 호환성용으로 유지돼요(클래스 속성, 클래스 생성 중 제거됨).

_order_ 속성은 Python 2와 Python 3 코드를 동기화하는 데 도움이 되도록 제공할 수 있어요. 열거형의 실제 순서와 검사되어, 둘이 일치하지 않으면 오류를 발생시켜요.

>>> class Color(Enum):
...     _order_ = 'RED GREEN BLUE'
...     RED = 1
...     BLUE = 3
...     GREEN = 2
...
Traceback (most recent call last):
...
TypeError: member order does not match _order_:
   ['RED', 'BLUE', 'GREEN']
   ['RED', 'GREEN', 'BLUE']

참고 — Python 2 코드에서는 정의 순서가 기록되기 전에 손실되므로 _order_ 속성이 필요해요.

버전 3.6에 추가됨.

ignore

_ignore_는 생성 중에만 사용되고, 생성이 완료되면 열거형에서 제거돼요.

_ignore_는 멤버가 되지 않을 이름들의 목록이고, 그 이름들도 완성된 열거형에서 제거돼요. 예제는 TimePeriod를 참고하세요.

버전 3.7에 추가됨.

dir(self)

['__class__', '__doc__', '__module__', 'name', 'value']self.__class__에 정의된 공개 메서드를 돌려줘요.

>>> from enum import Enum
>>> import datetime as dt
>>> class Weekday(Enum):
...     MONDAY = 1
...     TUESDAY = 2
...     WEDNESDAY = 3
...     THURSDAY = 4
...     FRIDAY = 5
...     SATURDAY = 6
...     SUNDAY = 7
...     @classmethod
...     def today(cls):
...         print(f'today is {cls(dt.date.today().isoweekday()).name}')
...
>>> dir(Weekday.SATURDAY)
['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value']

generate_next_value(name, start, count, last_values)

  • name — 정의 중인 멤버의 이름(예: 'RED').
  • start — Enum의 시작 값. 기본값은 1.
  • count — 이 멤버를 포함하지 않는, 현재 정의된 멤버 수.
  • last_values — 이전 값들의 리스트.

auto가 돌려줄 다음 값을 결정하는 데 사용되는 정적 메서드예요.

참고 — 표준 Enum 클래스에서 선택되는 다음 값은 본 최고 값에 1을 더한 값이에요. Flag 클래스에서는 다음 값이 다음으로 높은 2의 거듭제곱이 돼요.

이 메서드는 오버라이드할 수 있어요. 예:

>>> from enum import auto, Enum
>>> class PowersOfThree(Enum):
...     @staticmethod
...     def _generate_next_value_(name, start, count, last_values):
...         return 3 ** (count + 1)
...     FIRST = auto()
...     SECOND = auto()
...
>>> PowersOfThree.SECOND.value
9

버전 3.6에 추가됨. 버전 3.13에서 변경: 이전 버전은 최고 값 대신 마지막으로 본 값을 사용했음.

init(self, *args, **kwds)

기본적으로 아무것도 하지 않아요. 멤버 할당에 여러 값이 주어지면 그 값들이 __init__의 별도 인자가 돼요. 예:

>>> from enum import Enum
>>> class Weekday(Enum):
...     MONDAY = 1, 'Mon'

Weekday.__init__()Weekday.__init__(self, 1, 'Mon')으로 호출돼요.

init_subclass(cls, **kwds)

후속 하위 클래스를 더 구성하는 데 사용되는 클래스 메서드예요. 기본적으로 아무것도 하지 않아요.

missing(cls, value)

cls에서 찾을 수 없는 값을 조회하는 클래스 메서드예요. 기본적으로 아무것도 하지 않지만, 사용자 정의 검색 동작을 구현하도록 오버라이드할 수 있어요.

>>> from enum import auto, StrEnum
>>> class Build(StrEnum):
...     DEBUG = auto()
...     OPTIMIZED = auto()
...     @classmethod
...     def _missing_(cls, value):
...         value = value.lower()
...         for member in cls:
...             if member.value == value:
...                 return member
...         return None
...
>>> Build.DEBUG.value
'debug'
>>> Build('deBUG')
<Build.DEBUG: 'debug'>

버전 3.6에 추가됨.

new(cls, *args, **kwds)

기본적으로 존재하지 않아요. enum 클래스 정의나 믹스인 클래스(예: int)에서 지정하면, 멤버 할당에 주어진 모든 값이 전달돼요. 예:

>>> from enum import Enum
>>> class MyIntEnum(int, Enum):
...     TWENTYSIX = '1a', 16

이것은 int('1a', 16) 호출과 멤버 값 26을 만들어요.

참고 — 사용자 정의 __new__를 쓸 때는 super().__new__를 사용하지 말고 적절한 __new__를 호출하세요.

repr(self)

repr() 호출에 사용되는 문자열을 돌려줘요. 기본적으로 Enum 이름, 멤버 이름, 값을 돌려주지만 오버라이드할 수 있어요.

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __repr__(self):
...         cls_name = self.__class__.__name__
...         return f'{cls_name}.{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE')

str(self)

str() 호출에 사용되는 문자열을 돌려줘요. 기본적으로 Enum 이름과 멤버 이름을 돌려주지만 오버라이드할 수 있어요.

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __str__(self):
...         return f'{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(<OtherStyle.ALTERNATE: 1>, 'ALTERNATE', 'ALTERNATE')

format(self)

format()과 f-string 호출에 사용되는 문자열을 돌려줘요. 기본적으로 __str__() 반환 값을 돌려주지만 오버라이드할 수 있어요.

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __format__(self, spec):
...         return f'{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(<OtherStyle.ALTERNATE: 1>, 'OtherStyle.ALTERNATE', 'ALTERNATE')

참고Enum과 함께 auto를 쓰면 1부터 시작하는 증가하는 정수 값이 돼요.

버전 3.12에서 변경: Dataclass 지원 추가.

add_alias()

기존 멤버에 새 이름을 별칭으로 추가해요.

>>> Color.RED._add_alias_("ERROR")
>>> Color.ERROR
<Color.RED: 1>

이름이 이미 다른 멤버에 할당돼 있으면 NameError를 발생시켜요.

버전 3.13에 추가됨.

add_value_alias()

기존 멤버에 새 값을 별칭으로 추가해요.

>>> Color.RED._add_value_alias_(42)
>>> Color(42)
<Color.RED: 1>

값이 이미 다른 멤버와 연결돼 있으면 ValueError를 발생시켜요. 예제는 MultiValueEnum을 참고하세요.

버전 3.13에 추가됨.

class enum.IntEnum

IntEnumEnum과 같지만, 그 멤버는 정수이기도 하고 정수를 쓸 수 있는 곳 어디에든 쓸 수 있어요. IntEnum 멤버로 정수 연산을 수행하면 결과 값은 열거형 상태를 잃어요.

>>> from enum import IntEnum
>>> class Number(IntEnum):
...     ONE = 1
...     TWO = 2
...     THREE = 3
...
>>> Number.THREE
<Number.THREE: 3>
>>> Number.ONE + Number.TWO
3
>>> Number.THREE + 5
8
>>> Number.THREE == 3
True

참고IntEnum과 함께 auto를 쓰면 1부터 시작하는 증가하는 정수 값이 돼요.

버전 3.11에서 변경: 기존 상수 대체 사용 사례를 더 잘 지원하도록 __str__()이 이제 int.__str__()임. __format__()도 같은 이유로 이미 int.__format__()였음.

class enum.StrEnum

StrEnumEnum과 같지만, 그 멤버는 문자열이기도 하고 문자열을 쓸 수 있는 대부분의 같은 곳에 쓸 수 있어요. StrEnum 멤버로 수행되거나 함께 수행되는 어떤 문자열 연산의 결과도 열거형의 일부가 아니에요.

>>> from enum import StrEnum, auto
>>> class Color(StrEnum):
...     RED = 'r'
...     GREEN = 'g'
...     BLUE = 'b'
...     UNKNOWN = auto()
...
>>> Color.RED
<Color.RED: 'r'>
>>> Color.UNKNOWN
<Color.UNKNOWN: 'unknown'>
>>> str(Color.UNKNOWN)
'unknown'

참고 — 표준 라이브러리에는 str 하위 클래스 대신 정확한 str을 확인하는 곳이 있어요(즉 isinstance(unknown, str) 대신 type(unknown) == str). 그런 곳에서는 str(MyStrEnum.MY_MEMBER)를 사용해야 해요.

StrEnum과 함께 auto를 쓰면 소문자 멤버 이름이 값이 돼요.

__str__()은 기존 상수 대체 사용 사례를 더 잘 지원하도록 str.__str__()이에요. __format__()도 같은 이유로 str.__format__()이에요.

버전 3.11에 추가됨.

class enum.Flag

FlagEnum과 같지만, 그 멤버는 비트 연산자 &(AND), |(OR), ^(XOR), ~(INVERT)를 지원하고, 그 연산의 결과는 열거형의 (별칭인) 멤버예요.

contains(self, value)

valueself에 있으면 True를 돌려줘요.

>>> from enum import Flag, auto
>>> class Color(Flag):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> purple = Color.RED | Color.BLUE
>>> white = Color.RED | Color.GREEN | Color.BLUE
>>> Color.GREEN in purple
False
>>> Color.GREEN in white
True
>>> purple in white
True
>>> white in purple
False

iter(self)

포함된 모든 비-별칭 멤버를 돌려줘요.

>>> list(Color.RED)
[<Color.RED: 1>]
>>> list(purple)
[<Color.RED: 1>, <Color.BLUE: 4>]

버전 3.11에 추가됨.

len(self)

플래그의 멤버 수를 돌려줘요.

>>> len(Color.GREEN)
1
>>> len(white)
3

버전 3.11에 추가됨.

bool(self)

플래그에 멤버가 있으면 True, 없으면 False를 돌려줘요.

>>> bool(Color.GREEN)
True
>>> bool(white)
True
>>> black = Color(0)
>>> bool(black)
False

or(self, other)

현재 플래그에 other를 (이진) or한 결과를 돌려줘요.

>>> Color.RED | Color.GREEN
<Color.RED|GREEN: 3>

and(self, other)

현재 플래그에 other를 (이진) and한 결과를 돌려줘요.

>>> purple & white
<Color.RED|BLUE: 5>
>>> purple & Color.GREEN
<Color: 0>

xor(self, other)

현재 플래그에 other를 (이진) xor한 결과를 돌려줘요.

>>> purple ^ white
<Color.GREEN: 2>
>>> purple ^ Color.GREEN
<Color.RED|GREEN|BLUE: 7>

invert(self)

type(self)에서 self에 없는 모든 플래그를 돌려줘요.

>>> ~white
<Color: 0>
>>> ~purple
<Color.GREEN: 2>
>>> ~Color.RED
<Color.GREEN|BLUE: 6>

numeric_repr()

이름 없는 남은 숫자 값을 포맷하는 데 사용하는 함수. 기본값은 값의 repr이고, 흔한 선택은 hex()oct()이에요.

참고Flag와 함께 auto를 쓰면 1부터 시작하는 2의 거듭제곱 정수가 돼요.

버전 3.11에서 변경: 0 값 플래그의 repr()이 바뀌었어요. 이제 다음과 같아요. >>> Color(0)<Color: 0>