택시짱의 개발 노트

python decorator의 실행 순서는 어떻게? 본문

python

python decorator의 실행 순서는 어떻게?

택시짱 2022. 2. 20. 23:16

결론 : decorator의 호출 순서는 아래에서 위로!

 

django rest framwork에서 decorators method를 이용하여 view를 작성하고 있었다.

이때 permission_classes, api_view decorator를 같이 사용하고 싶었고 

나는 api_view -> permission_classes 순서로 호출되길 원했다.

 

이때 파이썬 코드는 절차적으로 진행 되니까 아래 코드 처럼 api_view를 위에, permission_classes를 그 다음으로 작성하니

Server Error가 뜨는 것이다..

# decorators의 순서가 올바르지 않음

@decorators.api_view(http_method_names=['POST'])
@decorators.permission_classes(permission_classes=AllowAny)
def kakaopay_ready(request):
    kakaopay = KakaoPayClient()
    user = request.user

    product = Product.objects.get(pk=request.data.get('product_pk'))
    quantity = request.data.get('quantity', 1)
    data = kakaopay.ready(user, product, quantity=quantity)
    return Response(data=data)
 
 >>> Internal Server Error: /kakaopay/

 

decorators의 순서를 바꿔주니 내가 원하는 대로 code가 동작하였다.

# decorators의 순서가 올바름

@decorators.permission_classes(permission_classes=AllowAny)
@decorators.api_view(http_method_names=['POST'])
def kakaopay_ready(request):
    kakaopay = KakaoPayClient()
    user = request.user

    product = Product.objects.get(pk=request.data.get('product_pk'))
    quantity = request.data.get('quantity', 1)
    data = kakaopay.ready(user, product, quantity=quantity)
    return Response(data=data)

 

 

그래서 왜 그런가 직접 코드를 작성해 보았다.

def decorator1(func):
    def wrapper(*args, **kwargs):
        print('decorator 1번')
        ret = func(*args, **kwargs) # <- 여기에 main 함수 (<function main at 0x7ff447cdf8c0>)
        return ret
    return wrapper


def decorator2(func):
    def wrapper(*args, **kwargs):
        print('decorator 2번')
        ret = func(*args, **kwargs) # <- 여기에 decorator 함수 (<function decorator2.<locals>.wrapper at 0x7ff447cdfef0>)
        return ret
    return wrapper


@decorator1
@decorator2
def main(str):
    print(str)


if __name__ == '__main__':
    main('main')
    
    


>>> decorator 1번
>>> decorator 2번
>>> main

 

디버깅을 돌리며 호출 순서를 확인해 보니까 decorator의 호출 순서는 위에서 아래로 내려가는 것을 알 수 있었다.

반응형
Comments