본문 바로가기
실버를 위한 코딩/파이썬 연습

[파이썬 연습] 파이썬 데코레이터

by forSilver 2024. 8. 12.
반응형

파이썬 데코레이터

파이썬 데코레이터(Decorator)는 기존 함수나 메서드에 추가적인 기능을 동적으로 부여하는 데 사용되는 디자인 패턴입니다. 데코레이터는 함수를 인자로 받아 새로운 함수를 반환하는 함수입니다. 데코레이터를 사용하면 코드의 재사용성을 높이고 중복을 줄일 수 있습니다.

기본 데코레이터 사용법

1. 기본 데코레이터 예제

먼저 간단한 데코레이터를 만들어 보겠습니다.

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

이 코드는 다음과 같은 출력을 생성합니다:

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

@my_decoratorsay_hello 함수를 my_decorator 함수로 장식(decorate)합니다. 이는 다음과 동일합니다:

say_hello = my_decorator(say_hello)

2. 매개변수가 있는 함수 데코레이터

매개변수가 있는 함수를 데코레이트하려면 데코레이터 내부의 래퍼 함수가 동일한 매개변수를 받아야 합니다.

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

이 코드는 다음과 같은 출력을 생성합니다:

Something is happening before the function is called.
Hello, Alice!
Something is happening after the function is called.

실습 과제

  1. 실행 시간을 측정하는 데코레이터를 작성하세요. 함수가 실행되는 데 걸린 시간을 출력해야 합니다.
  2. 함수 호출 횟수를 세는 데코레이터를 작성하세요. 각 호출 시마다 누적 호출 횟수를 출력해야 합니다.
  3. 사용자가 로그인했는지 확인하는 데코레이터를 작성하세요. 사용자가 로그인하지 않았으면 함수 실행을 막고 "로그인이 필요합니다." 메시지를 출력해야 합니다.

실습 과제 답안

1. 실행 시간을 측정하는 데코레이터

import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Function {func.__name__} executed in {end_time - start_time:.4f} seconds")
        return result
    return wrapper

@timer_decorator
def slow_function():
    time.sleep(2)
    print("Function finished")

slow_function()

2. 함수 호출 횟수를 세는 데코레이터

def count_calls_decorator(func):
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        print(f"Function {func.__name__} has been called {wrapper.calls} times")
        return func(*args, **kwargs)
    wrapper.calls = 0
    return wrapper

@count_calls_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")
say_hello("Bob")

3. 로그인 확인 데코레이터

logged_in = False  # 로그인 상태를 나타내는 전역 변수

def login_required(func):
    def wrapper(*args, **kwargs):
        if not logged_in:
            print("로그인이 필요합니다.")
            return
        return func(*args, **kwargs)
    return wrapper

@login_required
def view_dashboard():
    print("대시보드를 보여줍니다.")

view_dashboard()

로그인 상태를 나타내는 logged_in 변수를 True로 설정하면 데코레이터가 함수 호출을 허용합니다.

logged_in = True
view_dashboard()

 

이러한 데코레이터들을 사용하면 코드의 모듈화를 높이고 재사용성을 증가시킬 수 있습니다. 각 데코레이터는 특정 기능을 독립적으로 추가하므로, 코드의 유지보수와 확장이 용이해집니다.