ABOUT ME

IT와 컴퓨터 관련 팁, 파이썬 등과 아파트 정보, 일상적인 경험 등의 생활 정보를 정리해서 올리는 개인 블로그

  • [python] 파이썬 데코레이터 (Decorator)
    코딩 연습/코딩배우기 2020. 9. 16. 14:02
    반응형

     

    ■ 파이썬 데코레이터 (Decorator)는 꾸며주는(덧붙여주는) 역할을 하는 함수 또는 클래스로써 클러저와의 차이점은 함수를 다른 함수의 인자로 전달한다는 점이다. 즉, 데코레이터 함수가 인자로 전달된 함수를 기능이 추가된 새로운 함수로 만들고 이 함수를 반환한다.

    def smile():
        print('^_^')
    
    def confused():
        print('@_@')
    
    # 위 함수들의 결과를 'emoticon!'이라는 글이 위, 아래에 위치하도록 꾸며줄 수 있다. 
    
    
    def deco(func):  # 데코레이터 함수
        def wrap_func():
            print('emoticon!')
            func()
            print('emoticon!')
            
        return wrap_func
    
    
    smile_deco = deco(smile)
    smile_deco()
    
    '''
    emoticon!
    ^_^
    emoticon!
    '''
    
    confused_deco = deco(confused)
    confused_deco()
    
    '''
    emoticon!
    @_@
    emoticon!
    '''
    
    # 데코레이터 함수(deco)가 인자로 전달된 함수(smile, confused)에 기능을 추가
    

     

    ■ [전달 인자가 있는 함수 기반의 데코레이터]

    def adder2(n1, n2):
        return n1 + n2
    
    def adder3(n1, n2, n3):
        return n1 + n2 + n3
    
    
    def adder_deco(func):  # 데코레이터 함수
        def wrap_func(*args):  # 전달 인자를 튜플로 받는다.(튜플패킹)
            print(*args, sep = ' + ', end = ' ')  # 튜플언패킹
            print('= {0}'.format(func(*args)))  # 튜플언패킹
            
        return wrap_func
    
    
    adder2 = adder_deco(adder2)  
    # adder2 함수 객체를 인자로 넘기고, wrap_func 함수 객체 리턴
    
    ### 리턴된 함수 ###
    #wrap_func(*args):
    #    print(*args, sep = ' + ', end = ' ')
    #    print('= {0}'.format(func(*args)))  
    
    adder2(3, 4)  # 3 + 4 = 7
    # wrap_func(3, 4)와 같고, 내부 코드가 실행됨
    
    
    adder3 = adder_deco(adder3)
    adder3(1, 2, 3)  # 1 + 2 + 3 = 6
    
    

     

    good4me.co.kr

     

    ■ [전달 인자 2개 받는 경우의 데코레이터]

    def deco_func(func):
        def wrap_func(*args, **kwargs):
            print('{} 함수 호출 직전'.format(func.__name__))
            return func(*args, **kwargs)  # func() 호출 실행 후 리턴
        
        return wrap_func
    
    
    def param_func(p1, p2):
        print('내부 함수가 "{0}", "{1}" 매개변수를 받아 실행됨'.format(p1, p2))
    
    
    param_f = deco_func(param_func)
    param_f('토마토', 10)
    
    # param_func 함수 호출 직전
    # 내부 함수가 "토마토", "10" 매개변수를 받아 실행됨
    

     

    ■ [@ 기반으로 데코레이터 만들기]

    def deco2(func):
        def wrap_func():
            print('emoticon!')
            func()
            print('emoticon!')
            
        return wrap_func
    
    
    #def smile2():
    #    print('^_^')
    
    #smile_deco2 = deco2(smile2)
    #smile_deco2()
    
    # 위 주석 코드 대신에 아래처럼 @ 기호를 사용해도 동일한 결과임 
    
    @deco2
    def smile2():
        print('^_^')
    
    smile2()
    '''
    emoticon!
    ^_^
    emoticon!
    '''
    

     

    # 임의 숫자 여러 개 전달 시 더하기

    def adders(func):  # 데코레이터 함수
        def wrap_func(*args):
            print(*args, sep = ' + ', end = ' ')
            print('= {0}'.format(func(*args)))
        return wrap_func
    
    
    @adders   
    def adders(*args):
        return sum([n for n in args])
    
    
    import random
    
    n = random.sample(range(1, 100), random.randint(2, 10))
    
    adders(*n)  # 81 + 79 + 57 + 93 + 43 + 12 + 90 = 455
    
    
    

     

    [참고 자료] 윤성우의 열혈파이썬 중급편

     

    반응형
Designed by goodthings4me.