본문 바로가기
Python

클로저와 데코레이터 실습예시

by 좌우지간에 2024. 12. 26.

핵심 실습으로 정리한 클로저와 데코레이터


1. 클로저 핵심 실습:

실습 1: 간단한 카운터 클로저

def make_counter():
    count = 0

    def counter():
        nonlocal count
        count += 1
        return count

    return counter

counter = make_counter()
print(counter())  # 1 출력
print(counter())  # 2 출력

설명:

  • make_counter 함수는 count 변수를 초기화하고, counter 함수를 반환합니다.
  • 반환된 counter 함수는 make_counter 함수의 count 변수를 기억하고, 호출될 때마다 1씩 증가시킵니다.
  • 이것이 클로저의 가장 기본적인 형태입니다. 내부 함수가 외부 함수의 변수를 기억하는 것이 핵심입니다. 예를 들어, 여기서 make_counter 함수와 counter 함수를 주목하세요.

2. 데코레이터 핵심 실습:

실습 2: 함수 실행 시간 측정 데코레이터

import time

def elapsed(original_func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = original_func(*args, **kwargs)
        end = time.time()
        print(f"함수 `{original_func.__name__}` 실행 시간: {end - start:.4f}초")
        return result
    return wrapper


@elapsed
def my_func(n):
    time.sleep(n)  # n초 동안 실행
    return f"함수 실행 완료 ({n}초)"

my_func(2)  # 함수 실행 시간 출력

설명:

  • elapsed 데코레이터는 주어진 함수의 실행 시간을 측정하고 출력합니다.
  • @elapsed를 사용하여 my_func 함수에 데코레이터를 적용합니다.
  • my_func 함수를 호출하면, elapsed 데코레이터의 wrapper 함수가 먼저 실행되어 시간을 측정하고 원래 함수를 실행 후, 실행 시간을 출력합니다.
  • 데코레이터는 함수를 수정하지 않고 추가 기능을 적용할 수 있는 편리한 방법입니다. 여기서 elapsed 함수와 @elapsed를 눈여겨 보세요.

3. args, `kwargs` 핵심 사용 예시:

예시 3: 데코레이터에서 args, kwargs 사용

위의 elapsed 데코레이터 예시에서 이미 argskwargs를 사용했습니다. 이를 통해 입력 인수가 다양한 함수의 실행 시간을 측정할 수 있습니다.

@elapsed
def my_func_with_args(a, b, c="default"):
    time.sleep(1)
    return a + b + c

my_func_with_args(1, 2, c="hello") # 다양한 인수를 처리 가능

 


핵심 정리:

  • 클로저: 외부 함수의 변수를 기억하는 내부 함수, 변수를 캡처해서 사용하는 느낌
  • 데코레이터: 함수를 수정하지 않고 추가 기능을 적용 (시간 측정, 로깅 등)
  • args, kwargs: 함수에 전달되는 인수를 유연하게 처리할 때 사용

추가 설명:

  • 클로저는 함수가 반환될 때 함수 내부의 지역변수를 기억하고 사용하는 데에 핵심적인 역할을 합니다.
  • 데코레이터는 클로저를 활용하여 함수에 코드를 감싸는 패턴입니다.
  • argskwargs는 함수가 다양한 형태의 인수를 받아들일 수 있게 도와줍니다. 특히 데코레이터에서 원본 함수가 어떤 인수를 받을지 모를 때 유용하게 활용됩니다.