Skip to main content

데코레이터

데코레이터는 한국어로 번역하면 '장식하는 물체'입니다.

하지만 파이썬에서는 조금 다른 개념입니다.

데코레이터는 파이썬 함수를 장식하는 또 다른 함수로 함수에 추가 기능을 더합니다.

예시

어떤 수의 제곱근을 계산하는 함수를 만들어 보겠습니다.

밑에 있는 함수에 4를 입력하면 2가 출력이 됩니다.

하지만, 만일 a 값이 0보다 작다면 어떻게 대처를 할 수 있을까요?

조건문을 사용한다면 가능하겠지만 매우 복잡해집니다. 이 상황에서 데코레이터를 사용할 수 있습니다.

이제 우리가 원하는 값을 반환하는 함수를 만들겠습니다. 입력을 사용하여 사용자가 지정한 값을 반환하는 것도 가능하지만 이 예시에서는 쉽게 설명하기 위하여 -4를 돌려주는 함수를 만들겠습니다.

def returnVal():
return -4

위의 함수는 데코레이터의 예시입니다.

먼저, 데코레이터 함수를 만들기 위하여 메인 함수를 매개변수 안에 만듭니다.

mainFunction은 어떤 다른 함수에서 돌려주는 값(squreRootOf에서는 a의 제곱근)입니다.

함수 안에 또 다른 함수를 만들어서 func 변수 안에 저장하고 새로운 값인 abs() 함수를 사용하여 새로운 값을 돌려줍니다.

밑에 있는 예시를 확인하세요. 하지만 이렇게 하면 많이 복잡합니다.

그래서 파이썬에는 더 쉬운 방법이 있습니다.

사용 방법

데코레이터를 사용하기 위하여 returnVal() 함수를 선언하기 바로 전에 다음과 같은 코드를 붙여넣습니다.

@minusDecorator def returnVal():
return -4

위 코드의 첫 번째 매개변수는 함수이지만 @를 하면 바로 다음에 나오는 코드를 실행합니다.

returnVal()에서 돌려주는 절댓값을 계산하기 위하여 쉽게 returnVal() 함수만 사용하면 됩니다.

원래는 minusDecorator(returnVal())을 사용하여 절댓값을 계산하지만 @를 사용하면 바로 returnVal()을 실행해도 데코레이터에 있는 함수가 실행되어 절댓값을 출력할 수 있습니다.

2개 이상

데코레이터를 2개 이상 사용하기 위하여 @minusDecorator 밑에 또 다른 데코레이터 코드를 넣고 그다음에 함수를 넣을 수 있습니다.

@mydecorator

데코레이터를 사용하면 나만의 기능을 더 추가할 수 있습니다.

다음과 같은 클래스를 만들어 보겠습니다.

class Teacher:
def __init__(self, name, subjectTeaching):
self.name = name
self.subjectTeaching = subjectTeaching

def name(self):
return self.name

위의 클래스에서 선생님의 이름을 알기 위하여 name()을 사용해야 합니다.

하지만 @property를 사용한다면 name을 사용할 수 있습니다.

그래서 이 코드를 함수 앞에 넣으면 그 함수는 이제 클래스에서 변수가 됩니다.

@property def name(self):
return self.name

그리고 그 값을 바꿀 수도 있습니다.

@name.setter #name 함수의 값을 정하는 새로운 함수를 만들겠습니다

def name(self, val):
self.name = val

다음과 같은 코드를 실행할 수 있습니다.

myFavTeacher = Teacher("MR JAY")
print(myFavTeacher.name)

myFavTeacher.name = 'MS GOULD'
print(myFavTeacher.name)

또 값을 지울 수도 있습니다.

@name.deleter def name(self, val):
print('삭제하겠습니다….')
del self.name

@classmethod

클래스 값을 메서드로 바꿀 수도 있습니다.

하지만 이 코드 뒤에 나오는 함수에서 self는 항상 __init__() 밖에 있는 변수들입니다.

그래서 __init__() 안에 있는 변수는 다음 함수에서 존재하지 않습니다.

@staticmethod

다음에 나오는 함수는 클래스 안에서만 함수 또는 변수를 사용할 수 있습니다.

만일 클래스 밖에서 사용했다면 에러가 생길 것입니다.