본문 바로가기
Python

[Python] Week 22: 고급 문법 - 데코레이터

by cogito21_python 2024. 6. 1.
반응형

Day 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()
# Output:
# Something is happening before the function is called.
# Hello!
# Something is happening after the function is called.

 

Day 2: 함수 데코레이터

  • 강의 내용:
    • 함수 데코레이터의 개념
      • 함수 데코레이터 정의
      • 다양한 함수에 데코레이터 적용
    • 인자를 받는 함수 데코레이터
      • 가변 인자와 키워드 인자 처리
  • 실습:
    • 인자를 받는 함수 데코레이터 예제 작성
# 함수 데코레이터 정의
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Function is about to be called")
        result = func(*args, **kwargs)
        print("Function has been called")
        return result
    return wrapper

# 데코레이터 적용
@my_decorator
def greet(name):
    print(f"Hello, {name}!")

# 함수 호출
greet("Alice")
# Output:
# Function is about to be called
# Hello, Alice!
# Function has been called

 

Day 3: 클래스 메서드 데코레이터

  • 강의 내용:
    • 클래스 메서드 데코레이터의 개념
      • 클래스 메서드에 데코레이터 적용
      • @classmethod와 @staticmethod 데코레이터
    • 클래스 메서드 데코레이터 사용 예제
  • 실습:
    • 클래스 메서드 데코레이터 예제 작성
# 클래스 메서드 데코레이터 정의
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Method is about to be called")
        result = func(*args, **kwargs)
        print("Method has been called")
        return result
    return wrapper

class MyClass:
    @my_decorator
    def instance_method(self, value):
        print(f"Instance method called with value: {value}")

    @classmethod
    @my_decorator
    def class_method(cls, value):
        print(f"Class method called with value: {value}")

    @staticmethod
    @my_decorator
    def static_method(value):
        print(f"Static method called with value: {value}")

# 메서드 호출
obj = MyClass()
obj.instance_method(10)
MyClass.class_method(20)
MyClass.static_method(30)
# Output:
# Method is about to be called
# Instance method called with value: 10
# Method has been called
# Method is about to be called
# Class method called with value: 20
# Method has been called
# Method is about to be called
# Static method called with value: 30
# Method has been called

 

Day 4: 중첩 데코레이터

  • 강의 내용:
    • 중첩 데코레이터의 개념
      • 함수에 여러 개의 데코레이터 적용
    • 중첩 데코레이터 사용 예제
  • 실습:
    • 중첩 데코레이터를 사용하는 예제 작성
# 중첩 데코레이터 정의
def decorator_one(func):
    def wrapper(*args, **kwargs):
        print("Decorator One: Before the function call")
        result = func(*args, **kwargs)
        print("Decorator One: After the function call")
        return result
    return wrapper

def decorator_two(func):
    def wrapper(*args, **kwargs):
        print("Decorator Two: Before the function call")
        result = func(*args, **kwargs)
        print("Decorator Two: After the function call")
        return result
    return wrapper

# 중첩 데코레이터 적용
@decorator_one
@decorator_two
def say_hello(name):
    print(f"Hello, {name}!")

# 함수 호출
say_hello("Alice")
# Output:
# Decorator One: Before the function call
# Decorator Two: Before the function call
# Hello, Alice!
# Decorator Two: After the function call
# Decorator One: After the function call

 

Day 5: 데코레이터와 함수 속성

  • 강의 내용:
    • 데코레이터와 함수 속성 유지
      • functools.wraps 사용
      • 데코레이터의 함수 메타데이터 유지
    • 데코레이터와 함수 속성 사용 예제
  • 실습:
    • functools.wraps를 사용하는 예제 작성
import functools

# 데코레이터 정의
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("Before the function call")
        result = func(*args, **kwargs)
        print("After the function call")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """Greets the person with their name"""
    print(f"Hello, {name}!")

# 함수 호출 및 속성 확인
say_hello("Alice")
print(say_hello.__name__)  # 'say_hello'
print(say_hello.__doc__)  # 'Greets the person with their name'

 

Day 6: 고급 데코레이터

  • 강의 내용:
    • 인자를 받는 데코레이터
      • 데코레이터에 인자 전달
    • 고급 데코레이터 사용 예제
  • 실습:
    • 인자를 받는 데코레이터 예제 작성
import functools

# 인자를 받는 데코레이터 정의
def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator_repeat

@repeat(num_times=3)
def say_hello(name):
    print(f"Hello, {name}!")

# 함수 호출
say_hello("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!

 

Day 7: 데코레이터 종합 연습 및 프로젝트

  • 강의 내용:
    • 데코레이터 종합 연습 문제 풀이
      • 다양한 데코레이터 관련 문제
      • Q&A 세션
    • 미니 프로젝트
      • 주제 선정 및 프로그램 설계
      • 데코레이터를 활용한 프로그램 구현 및 테스트
  • 실습:
    • 종합 연습 문제 풀기
    • 미니 프로젝트 작성 및 발표
# 연습 문제 1: 실행 시간을 측정하는 데코레이터 작성
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Elapsed time: {end_time - start_time:.4f} seconds")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    print("Function complete")

slow_function()
# Output:
# Function complete
# Elapsed time: 1.000x seconds

# 연습 문제 2: 함수 호출 횟수를 세는 데코레이터 작성
def count_calls(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        print(f"Call {wrapper.calls} of {func.__name__}")
        return func(*args, **kwargs)
    wrapper.calls = 0
    return wrapper

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

say_hello("Alice")
say_hello("Bob")
# Output:
# Call 1 of say_hello
# Hello, Alice!
# Call 2 of say_hello
# Hello, Bob!

# 미니 프로젝트 예제: 로그인 상태를 확인하는 데코레이터
def requires_login(func):
    @functools.wraps(func)
    def wrapper(user, *args, **kwargs):
        if not user.get("is_logged_in"):
            print("User is not logged in")
            return
        return func(user, *args, **kwargs)
    return wrapper

@requires_login
def view_profile(user):
    print(f"User profile: {user['name']}")

# 사용자 객체
user1 = {"name": "Alice", "is_logged_in": True}
user2 = {"name": "Bob", "is_logged_in": False}

view_profile(user1)  # 'User profile: Alice'
view_profile(user2)  # 'User is not logged in'

 

이 강의는 파이썬의 고급 문법인 데코레이터를 익히는 것을 목표로 하며, 각 강의는 이론과 실습을 포함합니다. 다음 주차에 대한 상세 강의를 원하시면 말씀해 주세요!

반응형