PEP 354 – Python의 열거형
- Author:
- Ben Finney <ben+python at benfinney.id.au>
- Status:
- Superseded
- Type:
- Standards Track
- Created:
- 20-Dec-2005
- Python-Version:
- 2.6
- Post-History:
- 20-Dec-2005
- Superseded-By:
- 435
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
거부 통지
이 PEP는 거부되었습니다. 이 PEP는 기존 모듈 중 어느 곳(예: collections)에도 잘 들어맞지 않으며, Python 표준 라이브러리는 개별 데이터 구조를 각각의 모듈에 많이 두는 방식을 지양합니다. 또한 이 PEP는 광범위한 관심을 불러일으키지 못했습니다. 열거형이 필요한 경우에는 이러한 요구를 충족하는 쿡북 레시피와 PyPI 패키지가 있습니다.
참고: 이 PEP는 PEP 435에 의해 대체되었으며, 2013년 5월에 승인되었습니다.
초록
이 PEP는 Python을 위한 열거형 데이터 형식을 규정합니다.
열거형은 임의의 고유한 값에 바인딩된 기호 이름들의 배타적 집합입니다. 열거형 내의 값은 순회하고 비교할 수 있지만, 해당 값들은 열거형 외부의 값과 본질적인 관계가 없습니다.
동기
열거형의 속성은 정의된 순서는 있지만 본질적인 의미는 없는, 서로 관련된 불변 상수 값 집합을 정의하는 데 유용합니다. 전형적인 예로는 요일(일요일부터 토요일까지)과 학교 평가 등급(‘A’부터 ‘D’까지 및 ‘F’)이 있습니다. 그 밖의 예로는 오류 상태 값과 정의된 프로세스 내의 상태가 있습니다.
int 또는 str과 같은 다른 기본 형식의 값 시퀀스를 단순히 정의하여 개별적인 임의 값을 나타낼 수 있습니다. 그러나 열거형을 사용하면 이러한 값이 다른 모든 값과 구별되며, 의미 없는 연산(“수요일 곱하기 2”)이 해당 값에 대해 정의되지 않도록 보장합니다.
사양
열거형은 해당 형식 생성자에 전달되는 인자 시퀀스로 생성됩니다:
>>> Weekdays = enum('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')
>>> Grades = enum('A', 'B', 'C', 'D', 'F')
값이 없는 열거형은 의미가 없습니다. 생성자가 값 인자 없이 호출되면 EnumEmptyError예외가 발생합니다.
값은 새 열거형 객체의 속성에 바인딩됩니다:
>>> today = Weekdays.mon
값은 비교할 수 있습니다:
>>> if today == Weekdays.fri:
... print "Get ready for the weekend"
열거형 내의 값은 동일한 열거형의 값과 비교하는 경우를 제외하면 의미 있게 비교할 수 없습니다. 비교 연산 함수는 열거형의 값이 동일한 열거형에 속하지 않거나 다른 형식의 값과 비교될 때 NotImplemented [1]를 반환합니다:
>>> gym_night = Weekdays.wed
>>> gym_night.__cmp__(Weekdays.mon)
1
>>> gym_night.__cmp__(Weekdays.wed)
0
>>> gym_night.__cmp__(Weekdays.fri)
-1
>>> gym_night.__cmp__(23)
NotImplemented
>>> gym_night.__cmp__("wed")
NotImplemented
>>> gym_night.__cmp__(Grades.B)
NotImplemented
이를 통해 연산이 성공하고 부울 값으로 평가될 수 있습니다:
>>> gym_night = Weekdays.wed
>>> gym_night < Weekdays.mon
False
>>> gym_night < Weekdays.wed
False
>>> gym_night < Weekdays.fri
True
>>> gym_night < 23
False
>>> gym_night > 23
True
>>> gym_night > "wed"
True
>>> gym_night > Grades.B
True
열거형의 값을 str로 강제 변환하면 열거형을 생성할 때 해당 값에 지정한 문자열이 결과로 반환됩니다:
>>> gym_night = Weekdays.wed
>>> str(gym_night)
'wed'
열거형의 각 값에 대한 시퀀스 인덱스는 해당 값의 index 속성을 통해 정수로 내보내집니다:
>>> gym_night = Weekdays.wed
>>> gym_night.index
3
열거형은 순회할 수 있으며, 생성될 때 지정된 시퀀스 순서대로 해당 값들을 반환합니다:
>>> print [str(day) for day in Weekdays]
['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
열거형의 값은 해시 가능하며 딕셔너리 키로 사용할 수 있습니다:
>>> plans = {}
>>> plans[Weekdays.sat] = "Feed the horse"
열거형의 일반적인 용도는 데이터 형식에 가능한 값 집합을 제공하고, 이를 사용하여 해당 값에 관한 다른 정보에 매핑하는 것입니다:
>>> for report_grade in Grades:
... report_students[report_grade] = \
... [s for s in students if students.grade == report_grade]
근거 – 고려된 다른 설계
단일 클래스에 모두 포함
일부 구현에서는 열거형과 그 값이 모두 하나의 객체나 클래스의 속성으로 구성됩니다.
이 PEP에서는 열거형이 컨테이너이고 값이 단순 비교 가능 객체인 설계를 지정합니다. 열거형의 모든 속성을 하나의 클래스 안에 배치하려고 하면 뚜렷한 이점 없이 설계가 복잡해진다고 판단했습니다.
열거형 클래스를 생성하기 위한 메타클래스
이 PEP에서 지정하는 열거형은 enum유형의 인스턴스입니다. 일부 대안적 설계에서는 각 열거형을 자체 클래스로 구현하고, 모든 열거형의 공통 속성을 정의하는 메타클래스를 구현합니다.
각 열거형에 대해 인스턴스가 아니라 클래스를 두는 한 가지 동기는 기존 열거형을 확장하고 변경하는 서브클래스를 허용하기 위해서입니다. 그러나 클래스는 해당 클래스의 인스턴스가 생성된다는 것을 의미하므로, 각 인스턴스가 모든 요일을 포함하는 “요일” 클래스의 별도 인스턴스를 둔다는 것이 무엇을 의미하는지 상상하기 어렵습니다. 이로 인해 보통 각 클래스가 싱글턴 패턴을 따르게 되며, 설계가 더욱 복잡해집니다.
반면 이 PEP에서는 확장되거나 수정될 것으로 예상되지 않는 열거형을 지정합니다. 물론 기존 열거형의 문자열 값으로 새 열거형을 만들거나, 원한다면 enum유형을 서브클래스화할 수도 있습니다.
다른 유형과 관련된 값
일부 설계에서는 각 열거 값에 대해 특정 정수나 문자열과 같은 다른 값과의 강한 관계를 표현합니다.
이로 인해 열거형이 의미를 갖지 않는 맥락에서 그러한 값을 사용하게 되며, 설계를 불필요하게 복잡하게 만듭니다. 이 PEP에서 지정한 열거형 값은 자신을 생성하는 데 사용된 값을 노출하며, 다른 어떤 값과도 동등성 비교를 할 수 있지만, 열거형 밖의 값과의 순서 비교는 명시적으로 구현되어 있지 않습니다.
열거형 값의 속성 숨기기
이전 설계에서는 열거형 값이 문자열 키와 시퀀스 인덱스를 노출하지 않을 정도로 구현 내용을 최대한 숨기도록 했습니다.
이 PEP의 설계는 프로그램이 열거형 값의 열거형 타입, 시퀀스 인덱스, 그리고 해당 값에 지정된 문자열 키를 아는 것이 종종 편리하다는 점을 인정합니다. 이러한 정보는 열거형 값에 의해 속성으로 노출됩니다.
구현
이 설계는 부분적으로 Python Cookbook의 레시피 [2]에 기반합니다.
PyPI 패키지 enum [3]은 이 PEP에서 설명하는 데이터 타입의 Python 구현을 제공합니다.
참고 문헌과 각주
Copyright
This document has been placed in the public domain.