본문 바로가기
프로그래밍 언어(Programming Languages)/파이썬(Python)

[파이썬 Python] Python 데코레이터로 코딩을 혁신하는 6가지 방법 🐍✨

by 데이터 벌집 2025. 1. 12.
반응형

Python 데코레이터로 코딩 워크플로를 혁신하는 6가지 방법 🐍✨

Python 데코레이터로 코딩 워크플로를 혁신하는 6가지 방법 🐍✨

 

프로그래밍에서 코드를 얼마나 깔끔하고 효율적으로 작성하느냐는 개발자의 역량을 좌우합니다.
파이썬 데코레이터(Decorators)는 함수와 메서드의 동작을 손쉽게 확장하거나 수정할 수 있는 강력한 도구인데요, 활용하지 않으면 정말 아쉬운 기능입니다! 💡

 

이번 글에서는 데코레이터를 활용해 코딩 경험을 혁신할 수 있는 6가지 방법을 소개합니다. 💻
이 데코레이터들은 예제를 통해 쉽게 이해할 수 있도록 작성되었습니다. 🧸✨

 


문제: 반복되는 코드로 인한 비효율 😵

함수에서 자주 사용하는 로직, 예를 들어 성능 측정, 에러 처리, 로깅 등을 매번 구현하는 것은 매우 번거롭습니다. 이런 반복은 코드 품질을 떨어뜨리고 유지보수를 어렵게 만들죠.


해결책: 데코레이터로 문제 해결 🌟

데코레이터를 사용하면 중복된 코드를 없애고, 더욱 간결하고 재사용 가능한 코드를 작성할 수 있습니다.


1️⃣ 실행 시간 측정하기 ⏱️

특정 작업이 얼마나 오래 걸리는지 측정하고 싶을 때, 데코레이터를 사용하면 코드 중복 없이 간편하게 구현할 수 있습니다.

데코레이터: time_tracker

 
import time

def time_tracker(func):
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f"🐾 '{func.__name__}' 실행 시간: {end_time - start_time:.2f}초")
        return result
    return wrapper

예제: "토끼가 잠들지 않기 게임"

@time_tracker
def bunny_game(play_time):
    time.sleep(play_time)
    print("🐇 토끼가 무사히 뛰어다녔어요!")
    
bunny_game(3)

2️⃣ 에러 재시도 로직 구현하기 🔄

불안정한 외부 요청(API)이나 네트워크 작업에서 에러가 날 경우 자동으로 재시도하는 로직을 구현할 수 있습니다.

데코레이터: retry_handler

 
import time

def retry_handler(retries=3, delay=2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(retries):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"🚨 {attempt + 1}번째 시도 실패: {e}")
                    time.sleep(delay)
            raise Exception(f"💔 '{func.__name__}' 실패: 재시도 {retries}회 초과")
        return wrapper
    return decorator

예제: "곰돌이가 꿀단지를 찾는 모험"

import random

@retry_handler(retries=5, delay=1)
def bear_hunt():
    if random.random() < 0.7:
        raise ValueError("꿀단지를 못 찾았어요! 🐻🍯")
    print("🐻 꿀단지를 찾았어요!")
    
bear_hunt()

 


3️⃣ 타입 체크로 안전한 함수 호출 보장하기 ✅

인수의 타입을 미리 검사해 예상치 못한 에러를 방지할 수 있습니다.

데코레이터: type_checker

def type_checker(*expected_types):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for arg, expected in zip(args, expected_types):
                if not isinstance(arg, expected):
                    raise TypeError(f"⚠️ 예상 타입: {expected}, 받은 타입: {type(arg)}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

예제: "강아지가 공을 던지는 힘 계산"

@type_checker(int, float)
def puppy_throw(strength, distance):
    print(f"🐶 강아지가 {distance}m를 {strength}의 힘으로 공을 던졌어요!")

puppy_throw(10, 15.5)

4️⃣ 디버깅을 위한 함수 호출 로깅 🐛

함수의 입력값과 결과값을 자동으로 기록해 디버깅을 편리하게 할 수 있습니다.

데코레이터: debugger

def debugger(func):
    def wrapper(*args, **kwargs):
        print(f"🔍 '{func.__name__}' 호출 - 입력값: {args}, 키워드: {kwargs}")
        result = func(*args, **kwargs)
        print(f"✅ '{func.__name__}' 결과값: {result}")
        return result
    return wrapper

예제: "부엉이가 산수를 가르쳐요"

@debugger
def owl_math(a, b):
    return a + b

owl_math(3, 5)

5️⃣ 호출 횟수 제한하기 🚦

특정 시간 안에 너무 많은 요청이 발생하지 않도록 제한할 수 있습니다.

데코레이터: rate_limiter

import time

def rate_limiter(calls, period):
    def decorator(func):
        last_calls = []
        def wrapper(*args, **kwargs):
            nonlocal last_calls
            now = time.time()
            last_calls = [t for t in last_calls if now - t < period]
            if len(last_calls) >= calls:
                raise RuntimeError("🚫 호출 제한 초과!")
            last_calls.append(now)
            return func(*args, **kwargs)
        return wrapper
    return decorator

예제: "토끼가 친구들을 불러요"

@rate_limiter(calls=2, period=3)
def bunny_call():
    print("🐇 친구를 불렀어요!")

bunny_call()
time.sleep(2)
bunny_call()
# bunny_call()  # 제한 초과 🚫
 

6️⃣ 권한 확인하기 🔒

특정 작업을 수행하기 전에 사용자의 권한을 확인하는 로직을 추가할 수 있습니다.

데코레이터: permission_required

def permission_required(role):
    def decorator(func):
        def wrapper(*args, **kwargs):
            user_role = kwargs.get("role", "guest")
            if user_role != role:
                raise PermissionError(f"❌ '{role}' 권한이 필요합니다!")
            print(f"✅ 권한 확인 완료: {user_role}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

예제: "여우가 마을에 들어가기"

@permission_required(role="fox")
def enter_village(*args, **kwargs):
    print("🦊 여우가 마을에 들어왔어요!")

enter_village(role="fox")
# enter_village(role="rabbit")  # PermissionError 발생 🚫

마무리 🎉

이렇게 6가지 데코레이터를 활용하면 반복되는 작업을 줄이고, 코드의 가독성과 재사용성을 높일 수 있습니다. 🐾
여러분도 직접 만들어서 프로젝트에 적용해 보세요! 💪✨

 

💬 여러분의 데코레이터 활용 사례를 댓글로 공유해 주세요! 😊

반응형