본문 바로가기
Engineering WIKI/Python

Python 데코레이터

by wonos 2022. 5. 2.

정의

: 데코레이터는 함수를 수정하지 않은 상태에서 추가 기능을 구현할 때 사용합니다

def hello():
    print('hello 함수 시작')
    print('hello')
    print('hello 함수 끝')
 
def world():
    print('world 함수 시작')
    print('world')
    print('world 함수 끝')
 
hello()
world()
hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝

만약 다른 함수도 시작과 끝을 출력하고 싶다면 함수를 만들 때마다 print를 넣어야 합니다. 따라서 함수가 많아지면 매우 번거로워집니다.

이런 경우에는 데코레이터를 활용하면 편리합니다. 다음은 함수의 시작과 끝을 출력하는 데코레이터입니다.

def trace(func):                             # 호출할 함수를 매개변수로 받음
    def wrapper():                           # 호출할 함수를 감싸는 함수
        print(func.__name__, '함수 시작')    # __name__으로 함수 이름 출력
        func()                               # 매개변수로 받은 함수를 호출
        print(func.__name__, '함수 끝')
    return wrapper                           # wrapper 함수 반환
 
def hello():
    print('hello')
 
def world():
    print('world')
 
trace_hello = trace(hello)    # 데코레이터에 호출할 함수를 넣음
trace_hello()                 # 반환된 함수를 호출
trace_world = trace(world)    # 데코레이터에 호출할 함수를 넣음
trace_world()                 # 반환된 함수를 호출
hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝
  • 이제 @을 사용하여 좀 더 간편하게 데코레이터를 사용해보겠습니다. 다음과 같이 호출할 함수 위에 @데코레이터 형식으로 지정합니다.
def trace(func):                             # 호출할 함수를 매개변수로 받음
	def wrapper():
		print(func.__name__, '함수 시작')    # __name__으로 함수 이름 출력
		func()                               # 매개변수로 받은 함수를 호출
		print(func.__name__, '함수 끝')
	return wrapper                           # wrapper 함수 반환

@trace    # @데코레이터
def hello():
	print('hello')

@trace    # @데코레이터
def world():
	print('world')

hello()    # 함수를 그대로 호출
world()    # 함수를 그대로 호출
  • 데코레이터를 여러 개 지정하기
    • 함수에는 데코레이터를 여러 개 지정할 수 있습니다. 다음과 같이 함수 위에 데코레이터를 여러 줄로 지정해줍니다. 이때 데코레이터가 실행되는 순서는 위에서 아래 순입니다.
    @데코레이터1
    @데코레이터2
    def 함수이름():
        코드
    
    def decorator1(func):
        def wrapper():
            print('decorator1')
            func()
        return wrapper
     
    def decorator2(func):
        def wrapper():
            print('decorator2')
            func()
        return wrapper
     
    # 데코레이터를 여러 개 지정
    @decorator1
    @decorator2
    def hello():
        print('hello')
     
    hello()
    
    decorator1
    decorator2
    hello
    
    • @을 사용하지 않았을 때는 다음 코드와 동작이 같습니다.
    decorated_hello = decorator1(decorator2(hello))
    decorated_hello()
    

@데코레이터기능 함수명
def 함수명 () : 
    ...함수내용 정의하기
    return 중첩함수
@is_paid_user
def get_infomation() : 
    ...
  • 앞으로 get_infomation함수를 호출 할 때마다 데코레이터로 선언된 is_paid_user가 먼저 실행 될 것이다.

'Engineering WIKI > Python' 카테고리의 다른 글

collections 모듈 - defaultdict  (0) 2022.05.12
collections 모듈 - Counter  (0) 2022.05.12
vars() 내장함수  (0) 2022.05.10
파이썬 리스트 컴프리헨션  (0) 2022.05.04
파이썬 __ slots __  (0) 2022.04.28
파이썬 property(), @property  (0) 2022.04.25
파이썬 비트 논리연산자  (0) 2022.04.21
파이썬 정렬 함수 (rjust, ljust, zfill)  (0) 2022.04.20