Develop Story/python

decorator

꿈꾸는만학도 2023. 11. 5. 15:32
1. 정의

@staticmethod, @classmethod, @abstractmethod 처럼 함수의 시작부분 앞에 @표시를 하는것을 데코레이터라고 부른다. 이는 함수를 직접 수정하지 않고 함수 앞뒤에 기능을 추가해서 함수를 활용하는 방법이라 생각하면 된다. 

 

 

2. 인자가 없는 경우 데코레이터

예시를 보자. 다음 예시는 파이썬 코딩 도장에서 발췌한것임을 알려드린다.

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()    # 함수를 그대로 호출

 

@를 사용하지 않을떄는 다음과 같이 써야 하는 것이다.

trace_hello = trace(hello)    # 데코레이터에 호출할 함수를 넣음
trace_hello()                 # 반환된 함수를 호출
trace_world = trace(world)    # 데코레이터에 호출할 함수를 넣음
trace_world()                 # 반환된 함수를 호출

 

데코레이터도 기본은 중복코드 방지이다. 간편하게 사용할 수 있는 장점이 있다. 얼마나 간편한가...

 

결과는 다음과 같다. 

hello 함수 시작
hello
hello 함수 끝
world 함수 시작
world
world 함수 끝
3. 인자가 있는 경우의 데코레이터 
def div_out(function):
    def div_in(digit1, digit2):
        if digit2 == 0:
            print('cannot be divided with zero')
            return
        function(digit1, digit2)

    return div_in


@div_out
def divide(digit1, digit2):
    print(digit1 / digit2)


divide(4, 0)

==> caanot be divided with zero

 

4. 파라미터 제한 없는 decorator
def general(function):
    def wrapper(*args, **kwargs):
        print('this is general decorator')
        return function(*args, **kwargs)
    return wrapper
    
 
@general
def calc_squre(digit):
    return digit * digit

@general
def cal_plus(digit1, digit2):
    return digit1 + digit2

@general
def cal_quad(digit1, digit2, digit3, digit4):
    return digit1 * digit2 * digit3 * digit4
    


print (calc_squre(2))
this is general decorator
4

print(cal_plus(2, 3))
this is general decorator
5

print(cal_quad(1, 2, 3, 4))
this is general decorator
24

 

5. 여러 데코레이터 사용

 

def decorator1(function):
    def wrapper():
        print('decorator 1번입니다.')
        function()
    return wrapper

def decorator2(function):
    def wrapper():
        print('decorator 2번입니다.')
        function()
    return wrapper
    
    
    
    
@decorator1
@decorator2
def test():
    print('이것은 test deco입니까?')
    
    
test()
decorator 1번입니다.
decorator 2번입니다.
이것은 test deco입니까

'Develop Story > python' 카테고리의 다른 글

closure  (0) 2023.10.31
First class function  (0) 2023.10.31