CodeGym /자바 코스 /Python SELF KO /데코레이터의 모든 힘

데코레이터의 모든 힘

Python SELF KO
레벨 14 , 레슨 2
사용 가능

6.1 클래스 메서드를 위한 데코레이터

데코레이터는 클래스 메서드에도 사용할 수 있어. 중요한 것은 클래스 메서드에 올바르게 selfcls 인자를 전달해야 한다는 점이야.

클래스의 작동 원리는 아직 배우지 않았지만, 데코레이터가 이런 기능을 가지고 있다는 걸 알고 있으면 좋겠어.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"메서드 {func.__name__} 호출")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("MyClass에서 안녕!")
        
obj = MyClass()
obj.say_hello()

설명

데코레이터 (log_method_call): 이 데코레이터는 메서드 func를 받아 호출 전에 메시지를 출력하는 새로운 함수 wrapper를 반환해.

데코레이터가 적용된 클래스 메서드 (say_hello): say_hello 메서드는 log_method_call 데코레이터로 감싸져 있어, 호출 시 추가적인 행동을 더해주지.

출력:


메서드 say_hello 호출
MyClass에서 안녕!

6.2 여러 개의 데코레이터

한 함수에 여러 개의 데코레이터를 겹쳐 사용할 수 있어. 데코레이터는 선언된 반대 순서대로 적용돼.


def decorator1(func):
    def wrapper():
        print("데코레이터 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("데코레이터 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("안녕!")
        
say_hello()

설명

데코레이터 (decorator1와 decorator2): 이 데코레이터는 func 호출 전에 자신의 메시지를 추가해.

데코레이터가 적용된 함수 (say_hello): say_hello 함수는 두 데코레이터로 감싸져 있어. 먼저 decorator2가 적용되고, 그 다음 decorator1이 적용돼.

출력:


# 데코레이터 1
# 데코레이터 2
안녕!

6.3 내장 데코레이터

Python은 static methods, class methods, properties 같은 표준 작업을 위한 몇 가지 내장 데코레이터를 제공해.

@staticmethod

데코레이터 @staticmethod는 클래스 인스턴스 없이도 호출할 수 있는 정적 메서드를 만들 때 사용해.


class MyClass:
    @staticmethod
    def static_method():
        print("이것은 정적 메서드야.")
        
MyClass.static_method()

@classmethod

데코레이터 @classmethod는 인스턴스가 아니라 클래스를 첫 번째 인자로 받는 클래스 메서드를 만들 때 사용해.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"이것은 {cls.__name__} 클래스 메서드야.")
        
MyClass.class_method()

@property

데코레이터 @property는 속성의 getter, setter, deleter를 만들 때 사용해.


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # 출력: 10
obj.value = 20
print(obj.value)  # 출력: 20

이러한 내장 데코레이터는 Python 인터프리터 자체에서 올바르게 동작해.

6.4 데코레이터 사용 예제

로깅

데코레이터는 함수와 메서드 호출을 로깅하는 데 사용할 수 있어.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"함수 {func.__name__} 호출, 인자: {args}, 키워드 인자: {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

접근 제어

데코레이터는 함수와 메서드에 대한 접근을 제어하는 데 사용할 수 있어.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("사용자가 인증되지 않았어.")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("사용자 프로필")
        
user = User(is_authenticated=True)
user.view_profile()  # 성공적인 호출
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: 사용자가 인증되지 않았어.

캐싱

데코레이터는 함수 결과를 캐싱하는 데 사용할 수 있어.


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION