Python - Enum

holyja·2022년 5월 1일
0

파이썬

목록 보기
8/9
post-thumbnail

Enum


열거형 타입(Enumerated Type)

Enum은 열거형 타입(Enumerated Type) 이라고 불린다
열거형 타입이란 서로 관련된 상수들을 편리하게 선언하기 위한 목적으로 만들어진 타입이며, 미리 정의된 상수들을 모아둔 집합으로 특수한 데이터 유형이다.

해당 언어의 상수역할을 하는 식별자라고 생각할 수 있다.

파이썬에서는 기존에는 없다가 3.4v부터 추가되었다.

사용해보자.

enum의 사용은 우선 import를 진행해야 한다.

from enum import Enum

class MyEnum(Enum):
	BENCHPRESS = 1
    SQUAT      = 2
    DEADLIFT.  = 3
    
type(MyEnum)
>>>
<class 'enum.EnumMeta'>

type(MyEnum.BENCHPRESS)
>>>
<enum 'MyEnum'>

MyEnum의 타입은 enum클래로 나오고, MyEnum의 벤치프레스 또한 enum형태의 MyEnum클래스로 나온다.
Enum은 상수역할을 하는 식별자라고 했으니, 변수명 또한 전부 대문자로 해주어야 한다는 것을 기억하자.

호출을 하기 위해서는 아래처럼 두 가지 방법으로 진행하면 된다.

MyEnum['BENCHPRESS']
>>>
<MyEnum.BENCHPRESS: 1>

MyEnum.BENCHPRESS
>>>
<MyEnum.BENCHPRESS: 1>

마치 dictionary의 형태와 비슷해보이지만, 실제 key와 value처럼 사용하기 위해서는 아래와 같이 명령을 해야한다.

MyEnum.BENCHPRESS.name
>>>
'BENCHPRESS'

MyEnum.BENCHPRESS.name
>>>
1

또한 enum은 열거한 순서대로 iteration을 지원한다. 즉, iterable object란 뜻이다. 확인해보자.
해당 객체가 이터러블 객체인지 확인하기 위해서는 collections 모듈로 확인해볼 수 있다.

import collections

myenum = MyEnum

isinstance(myenum, Iterable)
>>>
<stdin>:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working
True

위에는 collections 대신 collections.abc를 사용하라는 경고와 함께 True 로 리턴되는 것을 확인할 수 있다. collections 모듈이 뭔지는 나중에 더 확인해보자. 지금은 Enum을 학습중이니깐!

그럼 한번 for문으로 출력을 진행해보자.

for myenum in MyEnum:
	print(myenum)
>>>
MyEnum.BENCHPRESS
MyEnum.SQUAT
MyEnum.DEADLIFT

사전형태에서 Key가 출력되듯이 name들만 출력되는 것을 확인할 수 있다. 그럼 value로 되나?

for myenum in MyEnum:
	print(myenum.value)
>>>
1
2
3

# 사전처럼 출력해보자.
for name, member in MyEnum.__members__.items():
	print(name, member.value, sep=":")
>>>
BENCHPRESS:1
SQUAT:2
DEADLIFT:3

되는 것을 확인했다.

아, 만약 숫자를 일일이 넣어주는게 귀찮다면 auto()함수를 이용할 수 있다.
다만 enum 라이브러리의 auto함수라는 것을 기억해야 한다. Import를 살짝 다르게 해줘야 한다는 뜻이다.

import enum

class MyEnum(enum.Enum):
	BENCH = enum.auto()
    SQUAT = enum.auto()
    DEAD. = enum.auto()
    
for enum in MyEnum2:
	enum
>>>
<MyEnum2.BENCH: 1>
<MyEnum2.SQUAT: 2>
<MyEnum2.DEAD: 3>

auto함수를 사용하면 자동으로 1부터 부여해주는 것을 확인할 수 있다.

왜 쓰지?

enum을 사용하면 특정 상태를 하나의 집합으로 만들어 관리할 수 있기 때문에 사용하면 가독성이 높아지고 문서화를 하는데 도움이 된다.

보다 상세한 내용은 공식문서를 확인하자.

공식문서

enumerate


별개지만 enumerate()라는 함수도 있다. 간단하게 알아보자.
enumerate는 순서가 있는 자료형(List, Set, Tuple 등)을 Index를 포함한 enumerate객체로 리턴해준다.

사용하는 방법은 아래와 같다.

a = [1, 2, 3, 2, 45, 2, 5]
b = enumerate(a)
b
>>>
<enumerate object at 0x7fdb5004cd40>

dir(b)
>>>
['__class__', '__class_getitem__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

__iter__와 __next__가 있는 것을 보니 enumerate 또한 iterable 인 것 같다.
혹시 모르니 확인해보자.

isinstance(b, collections.Iterable)
>>>
True

맞다. 그럼 for문을 사용해서 출력해보자.

 for i in b:
	print(i)
>>>
(0, 1)
(1, 2)
(2, 3)
(3, 2)
(4, 45)
(5, 2)
(6, 4)

오! enumerate 객체인 b를 하나씩 출력해주니, 해당 Index와 값이 튜플에 담겨서 출력이 되었다.
그럼 이렇게도 될 것 같다.

for i,v in b:
	print(i, v)
>>>
# 아무일 없다.

for i,v in enumerate(a):
	print(i, v)
>>>
0 1
1 2
2 3
3 2
4 45
5 2
6 4

나중에 몇번째 index인지 확인할 때 유용하게 사용할 수 있을 것 같다.

profile
소통하고 발전하자. 그리고 기록하자.

0개의 댓글