본문 바로가기
공부/Python

[Python] @Decorator 파이썬 @데코레이터

by 병진들 2021. 6. 11.

포스팅하기에 앞서..

처음에 Decorator라는 기능을 접했을때, 그래서 이게뭐? 이게 필요한가..? 이런멍청한 생각을 많이 했었다.

개념을 찾아보고 사례를 봐도, 굳이...? 라는 생각도 있었고..(사실 잘 이해를못한거였음)

 

근데 내가 필요해지니 쉽게느껴지더라..!!

 

회사에서 일을 하다가, 특정 몇가지 함수들의 실행시간을 측정해야 할 일이 있었다..

사실 이러한 상황에서 데코레이터를 사용하는게 과연 옳은 일일까? 라는 고민은 아직도 있다. 사수가 없어서 슬프다..

(혹시 이런 방법이 옳지 않다면 댓글로 알려주시길 부탁드립니다ㅠㅠ)

 

내가 이해한 Decorator 정의

말 그대로 함수 자체를 인자값으로 받아 그 함수를 실행할때 마다 꾸며주는 함수이다.

 

 

사용 이유!

내가 원하는 함수만 골라서 실행 시간을 측정하고 싶음!

 

 

먼저 Decorator 함수를 만들어보자

def timeChecker(func):
    """@데코레이터
    함수(func) 별 소요시간 체크
    """
    def wrapper(_):
        start = time.time()
        func(_)
        during = time.time() - start
        print(f"{func.__name__}함수의 소요시간 : {during}")
    return wrapper

내가 원하는(꾸며줄) 실행 함수의 소요시간을 체크하고 싶기 때문에, start에 해당 함수가 시작하는 시간을 넣고

func()으로 함수가 실행된 후에 다시 time을 체크하여 start와 빼주면 실질적인 함수의 실행시간이 나온다.

func를 인자로 받았기 때문에, func.__name__ 도 가능한데, 이 변수에는 실행한 함수의 이름이 저장되어 있다

 

 

사용방법

굉장히 쉽다! 그냥 내가 꾸며주고 싶은 함수 위에 @timeChecker 만 붙여주면 된다!

간단한 예시로, 버블정렬과 선택정렬에 시간체크용 데코레이터를 붙여주었다.

@timeChecker
def bubbleSort(alist):
    """
    # 버블정렬(Bubble Sort)
     - 시간복잡도 O(n^2)
     - 공간복잡도 O(n) : 하나의 배열만 사용하기 때문
    """
    for loof_count in range(len(alist)-1, 0, -1):
        for idx in range(loof_count):
            if alist[idx] > alist[idx +1]:
                tmp = alist[idx+1]
                alist[idx+1] = alist[idx]
                alist[idx] = tmp
    print(f"Bubble Sort: {alist} ")

@timeChecker
def selectionSort(alist):
    """
    # 선택정렬(Selection Sort)
     - 한번 순회를 하면서 가장 작은 수를 찾아서 배열의 마지막 위치와 교환(제일작은걸 가장 앞으로)
     - 시간복잡도 O(n^2)
    """
    for offset in range(0, len(alist)-1):
        offset_min = offset
        for num in range(offset+1, len(alist)):
            # 최소값(offset_min)보다 새로 탐색하는 값(num)이 작으면 최소값 가리키는 포인터 갱신
            if alist[offset_min] > alist[num]:
                offset_min = num
        tmp = alist[offset_min]
        alist[offset_min] = alist[offset]
        alist[offset] = tmp
    print(f"Selection Sort: {alist}")

 

실행

size = 10
array_ = [randint(1,10000000) for x in range(size) ]
print(f"정렬 전 : {array_}")
bubbleSort(array_)
selectionSort(array_)

 

결과

정렬 전 : [392370, 81484, 164341, 872842, 502900, 768861, 497492, 695114, 306037, 203214]
Bubble Sort: [81484, 164341, 203214, 306037, 392370, 497492, 502900, 695114, 768861, 872842]   
bubbleSort 함수의 소요시간 : 0.0
Selection Sort: [81484, 164341, 203214, 306037, 392370, 497492, 502900, 695114, 768861, 872842]
selectionSort 함수의 소요시간 : 0.0

 

 

사실 정렬같은 함수는 워낙 실행시간이 짧아서..ㅎㅎㅎ 

하지만 저 위 함수는 예시일 뿐, 실제로 오래걸리는 함수로 테스트해보면 잘 나온다!

댓글