Python의 열거형이 코드 가독성을 향상시키는 방법
열거형은 C, C++, Java 등 다양한 프로그래밍 언어에서 흔히 사용되는 자료형입니다. 이는 코드를 더 안전하고 이해하기 쉽게 만들어주는 데 기여합니다.
파이썬에서는 과거에 열거형이 기본적으로 지원되지 않았습니다. 하지만 3.4 버전부터 파이썬은 열거형을 공식적으로 지원하기 시작했습니다. 이 글에서는 열거형을 생성하고 활용하는 방법과, 이를 통해 코드의 가독성을 어떻게 향상시킬 수 있는지에 대한 지침을 제공합니다.
열거형이란 무엇이며, 어떤 기능을 수행할까요?
열거형, 또는 enum은 특정 값의 집합으로 정의되는 자료형을 의미합니다. 이러한 값의 집합을 해당 멤버 집합이라고 부릅니다. 열거형을 사용하면 변수가 가질 수 있는 값의 범위를 제한할 수 있습니다. 이는 코드의 안정성을 높이는 데 도움이 되며, 동시에 가독성 또한 향상시킵니다.
알아두어야 할 몇 가지 핵심 용어
열거형을 논의할 때 자주 사용되는 몇 가지 용어를 먼저 정의하는 것이 중요합니다. 이는 '멤버'와 '값'입니다.
- 멤버: 열거형을 구성하는 명명된 상수들을 의미합니다. 예를 들어, '요일'이라는 열거형은 '일요일', '월요일', '화요일' 등의 멤버를 가질 수 있습니다.
- 값: 각 열거형 멤버를 내부적으로 구별하기 위해 사용되는 고유한 값을 말합니다. 이를 통해 멤버 간의 비교가 가능해집니다. '요일' 열거형에서 '일요일'은 0, '월요일'은 1, '화요일'은 2와 같은 값을 가질 수 있습니다.
이제 열거형이 코드를 어떻게 개선하는지 살펴보겠습니다.
열거형이 코드 품질을 향상시키는 방법
열거형은 코드를 더 읽기 쉽고 유지보수하기 용이하게 만들며, 오류 발생 가능성을 줄이는 데 기여합니다. 열거형을 사용해야 하는 몇 가지 주요 이유는 다음과 같습니다.
- 열거형을 사용하면 변수나 함수 인수가 기대하는 값을 명확하게 지정할 수 있습니다. 이렇게 함으로써 코드의 의도를 더욱 명확하게 전달하여 다른 개발자들이 코드를 이해하기 쉽게 만들 수 있습니다.
- 열거형은 코드 자체를 문서화하는 역할을 합니다. 즉, 함수에 필요한 값들을 설명하기 위해 별도의 주석이나 문서를 추가할 필요가 없습니다. 열거형 자체가 어떤 값이 허용되는지를 명시적으로 나타냅니다.
- 또한, 열거형은 잘못된 값을 전달할 때 IDE가 오류를 강조 표시하고 자동 완성 기능을 제공하여 개발 과정을 효율적으로 만듭니다.
- 결과적으로, 코드는 더욱 안정적이고 타입 안전성을 확보하게 되며, 런타임 오류의 가능성을 줄일 수 있습니다.
이제 파이썬에서 열거형을 생성하는 방법을 알아보겠습니다.
파이썬에서 열거형을 만드는 방법
파이썬은 열거형을 기본적으로 지원하지 않지만, 표준 라이브러리에서 `enum` 모듈을 제공하여 열거형을 사용할 수 있게 합니다. 이 튜토리얼에서는 `enum` 모듈을 활용합니다. 파이썬에서 열거형을 만드는 방법은 크게 클래스 방식과 함수 방식 두 가지로 나눌 수 있습니다. 이 섹션에서는 두 가지 방법을 모두 자세히 살펴보겠습니다.
사전 준비 사항
이 튜토리얼을 따라 하려면 파이썬 3.4 버전 이상이 설치되어 있어야 합니다. 이 버전부터 표준 라이브러리에 `enum` 모듈이 포함되어 있습니다. 혹시 아직 설치하지 않았다면, 다음 자료를 참고하시기 바랍니다.

또한 이 튜토리얼을 진행하려면 파이썬의 기본 문법과 클래스 및 상속과 같은 객체 지향 프로그래밍 개념에 대한 기본적인 이해가 필요합니다.
#1. 클래스 방식
열거형을 만드는 첫 번째 방법은 클래스를 이용하는 것입니다. 먼저 `enum` 모듈에서 `Enum` 클래스를 임포트합니다. 그런 다음, `Enum` 클래스를 상속받는 새로운 클래스를 정의하여 열거형을 만듭니다.
from enum import Enum
class Direction(Enum):
NORTH = 0
EAST = 1
SOUTH = 2
WEST = 3
열거형 멤버에 원하는 값을 할당할 수도 있습니다. 예를 들어, 위 예시에서 방향 열거형에 0, 1, 2, 3 대신 각각 0, 90, 180, 270과 같은 각 방향에 해당하는 각도를 값으로 할당할 수 있습니다.
from enum import Enum
class Direction(Enum):
NORTH = 0
EAST = 90
SOUTH = 180
WEST = 270
또는 `range` 함수를 사용하여 위와 동일한 결과를 더 간결하게 얻을 수 있습니다. 다음 코드는 `range` 함수를 사용하여 값을 생성하는 방법을 보여줍니다.
from enum import Enum
class Direction(Enum):
NORTH, EAST, SOUTH, WEST = range(0, 360, 90)
이 경우 `range` 함수를 사용하여 0부터 360까지 90씩 증가하는 값들을 생성합니다. 생성된 값들은 튜플 언패킹과 유사한 방식으로 각 열거형 멤버에 할당됩니다. 튜플 언패킹에 대해 더 자세히 알고 싶으시다면, 파이썬의 튜플 관련 자료를 참고해 주세요.
`Enum` 클래스는 추상 클래스입니다. 즉, 인스턴스를 생성할 의도가 없다는 의미입니다. 대신, 열거형 멤버에 해당하는 속성에 직접 접근하여 사용합니다.
#2. 함수 방식
함수 방식은 클래스 상속 방식의 대안으로 사용할 수 있습니다.
from enum import Enum
Direction = Enum("Direction", ["NORTH", "EAST", "SOUTH", "WEST"])
위 코드 조각은 `Direction`이라는 이름의 열거형을 생성합니다. 두 번째 인자로 제공된 네 개의 멤버를 통해 열거형에 접근할 수 있습니다. 기본적으로 각 멤버에는 1부터 시작하는 정수 값이 할당됩니다. 즉, `NORTH`는 1, `EAST`는 2와 같이 순서대로 값이 매겨집니다. 이는 일반적으로 예상되는 0 기반 인덱스와 다른데, 이는 0이 거짓(False) 값이기 때문에 모든 값을 참(True)으로 만들기 위해 1부터 시작하는 인덱스를 사용하는 것입니다.
또는 멤버에 값을 할당하기 위해 각 멤버의 이름과 값을 튜플 형태로 묶어 리스트로 전달할 수도 있습니다.
from enum import Enum
Direction = Enum(
name = "Direction",
values = [
("NORTH", "n"),
("EAST", "e"),
("SOUTH", "s"),
("WEST", "w"),
]
)
위 예시에서는 정수 대신 문자열을 사용하여 멤버의 값을 할당했습니다. 이는 값을 할당할 때 문자열 또한 정수와 마찬가지로 유효하다는 것을 보여줍니다.
열거형 활용법
이전 섹션에서는 열거형을 생성하고 멤버에 값을 할당하는 방법을 알아보았습니다. 이번 섹션에서는 열거형을 사용하여 멤버에 접근하고 할당하는 방법, 그리고 열거형 멤버 간의 동등성을 확인하는 방법을 살펴보겠습니다.
멤버 접근 방법
열거형의 멤버에 접근하는 방법은 여러 가지가 있습니다. 점 표기법, 괄호 표기법, 대괄호 표기법 등이 있습니다. 다음 예시는 이러한 다양한 방법을 보여줍니다.
from enum import Enum
# 열거형 생성
class Day(Enum):
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY = range(1, 8)
# 열거형 멤버에 접근
# 1. 점 표기법 사용
print(Day.SUNDAY)
# 2. 대괄호 표기법 사용
print(Day["MONDAY"])
# 3. 괄호 표기법 사용
print(Day(3))
열거형 멤버에 접근한 후에는 해당 멤버를 변수에 저장할 수 있습니다. 멤버에 접근하면 해당 값이나 이름이 아닌 멤버 객체에 대한 참조가 반환됩니다. 다음 섹션에서는 이 점을 유념해야 합니다.
이름과 값에 접근
앞서 언급했듯이, 열거형 멤버에 접근하면 해당 멤버 객체에 대한 참조가 생성됩니다. 멤버 객체의 이름이나 값에 접근하려면, 객체의 `name`과 `value` 속성을 사용할 수 있습니다.
print(Day.SUNDAY.name, Day.SUNDAY.value)

동등성 확인
열거형 멤버를 변수에 할당하면 열거형 멤버 객체에 대한 참조가 생성된다는 점을 기억해야 합니다. 따라서 변수에 특정 열거형 멤버가 할당되었는지 확인하려면, `is` 연산자를 사용하여 변수와 열거형 멤버가 동일한 객체를 가리키는지 확인해야 합니다.
다음은 이를 보여주는 예시입니다.
today = Day.WEDNESDAY
if today is Day.MONDAY:
print("월요일이다, ㅠㅠ")
if today is Day.WEDNESDAY:
print("행복한 수요일!")

또는 `==` 연산자를 사용할 수도 있습니다. `Enum` 클래스의 상위 클래스에서 `==` 연산자는 `is` 연산자에 대한 래퍼입니다. 이는 연산자 오버로딩을 통해 구현됩니다. 연산자 오버로딩에 대한 자세한 내용은 매직 메서드 관련 자료에서 확인할 수 있습니다. 어쨌든, `is` 대신 `==`를 사용한 예시는 다음과 같습니다.
today = Day.WEDNESDAY
if today == Day.MONDAY:
print("월요일이다, ㅠㅠ")
if today == Day.WEDNESDAY:
print("행복한 수요일!")

반복되는 위험을 피하기 위해 열거형 비교는 값이 아닌 객체 ID를 확인합니다.
마무리
이 글에서는 열거형이 무엇인지, 왜 유용한지에 대해 알아보았습니다. 또한 `Enum` 클래스를 상속하여 열거형을 만들거나 함수형 API를 사용하는 다양한 방법을 살펴보았습니다.
열거형을 사용하고, 값에 접근하고, 열거형 멤버를 비교하는 방법 또한 다루었습니다. 다음으로는 TypeScript 열거형에 대한 자료를 읽어보시는 것을 추천합니다.