본문 바로가기

코딩/Python

[Python/파이썬] 함수 속의 함수 - 데코레이터(Decorator) 1편

반응형

1편 : 2021.07.14 - [코딩/Python] - [Python/파이썬] 함수 속의 함수 - 데코레이터(Decorator) 기초

2편 : 2021.07.16 - [코딩/Python] - [파이썬/Python] 매개변수 있는 함수에 데코레이터 적용

 

  PyQt의 시그널(Signal)과 슬롯(Slot) 개념을 공부하는 도중에 데코레이터(Decorator)라는 부분이 나와 궁금해 작성해보는 포스팅. 파이썬에서는 데코레이터(Decorator)라고 하는 개념이 있다. 영어 단어 뜻대로 하면 '장식자'라는 의미인데 함수를 꾸며주는 역할을 한다고 한다. 쉽게 말하면 어떤 함수에 기능을 추가할 때, 본 함수를 수정하지 않고 장식처럼 사용할 수 있는 기능이다. 

 

  아래 예시를 통해 알아보도록 하자. 

 

 

<코드>

def race():
    print("경주마가 출발했습니다.")
    for num in range(0,10):
        print(str(num)+"km 달리는 중입니다.")
    print("경주마가 결승선에 도착했습니다.")


race()

 

<결과>

경주마가 출발했습니다.
0km 달리는 중입니다.
1km 달리는 중입니다.
2km 달리는 중입니다.
3km 달리는 중입니다.
4km 달리는 중입니다.
5km 달리는 중입니다.
6km 달리는 중입니다.
7km 달리는 중입니다.
8km 달리는 중입니다.
9km 달리는 중입니다.
경주마가 결승선에 도착했습니다.

 

 

   경주마가 출발부터~도착까지 출력하는 간단한 함수이다.(race) 이 함수에 경주마가 출발과 도착 전에 한 행동을 추가하는 함수를 작성해보자. 원래 함수인 race를 건드리지 않고 데코레이터를 사용할 것이다. 해당 코드는 '파이선 코딩 도장'의 42.1 단원을 참고했다.

 

 

<코드>

#데코레이터 함수 정의
def decoFunction(inputFunc): #원래 함수를 매개변수로 입력 받음
    def wrapper():
        print("경주마가 쉬고 있어요.")
        inputFunc() #원래 함수 호출
        print("경주마가 배가 고픕니다")
    return wrapper #데코레이터가 추가 된 함수 리턴

#데코레이터를 사용하려면 @데코레이터 함수명 을 원래 함수위에 써줘야 함.
@decoFunction
def race():
    print("경주마가 출발했습니다.")
    for num in range(0,10):
        print(str(num)+"km 달리는 중입니다.")
    print("경주마가 결승선에 도착했습니다.")


race()

 

<결과>

경주마가 쉬고 있어요.
경주마가 출발했습니다.
0km 달리는 중입니다.
.
.
.
9km 달리는 중입니다.
경주마가 결승선에 도착했습니다.
경주마가 배가 고픕니다

 

 

  이전에 클래스에 대한 포스팅을 진행할 때, 추상클래스 사용법에서 @abstractmethod 를 써줬던 부분을 언급했었다. 여기서 @를 표시한 내용이 데코레이터를 의미하는 부분이다.

(참고링크 : 2021.03.22 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수)

 

  결과를 도식화하면 아래와 같다. 원래 함수 race( ) 를 decorator 함수 입력 매개변수로 받는다. deco_Function 내부 함수에서 장식을 달아서 return시킨다. 즉, decorator 함수의 return값은 원래 함수에 장식을 단 또 다른 함수이다.

 

 

  데코레이터 함수를 사용하는 방법에는 2가지 방식이 있는데 아래 방법1인  '@데코레이터 함수명'을 기입하는 부분만 기억해도 무관하다. 원래 함수 위에 @데코레이터 함수명만 써주면 해당 함수가 데코레이터를 포함시켜 동작한다. 위에서 동작시켰던@decoFunction이 그 부분이다. 방법2는 이런게 있다 정도만 알아두자.

 

 

<방법1 : 원래 함수 위에 @데코레이터 함수명 기입하기>

@decoFunction
def race():
    print("경주마가 출발했습니다.")
    for num in range(0,10):
        print(str(num)+"km 달리는 중입니다.")
    print("경주마가 결승선에 도착했습니다.")

 

<방법2 : 원래 함수를 데코레이터 함수로 직접 감싸기>

deco_race = decoFunction(race) #수동으로 원래함수를 데코로 감싸기, 이때는 @ 을 중복해서 사용 x
deco_race() #데코로 감싸진 함수 호출

 

  주의해야할 점은 decoFunction이 원래 함수인 race( )보다 먼저 정의되어 있어야 오류가 발생하지 않는다.

 

  데코레이터를 사용하면 원래 함수를 수정하지 않고도 기능을 추가할 수 있어 로그 남기기, 시간 측정 등에서 사용되고 있는 듯 하다. 위에서 다룬 내용은 데코레이터에 대한 기초적인 내용이고, 좀 더 복잡한 내용은 다음 포스팅에서 정리해본다.

 


 

참고링크1 : 코딩 도장

 

파이썬 코딩 도장: 42.1 데코레이터 만들기

Unit 42. 데코레이터 사용하기 파이썬은 데코레이터(decorator)라는 기능을 제공합니다. 데코레이터는 장식하다, 꾸미다라는 뜻의 decorate에 er(or)을 붙인 말인데 장식하는 도구 정도로 설명할 수 있습

dojang.io

 

728x90