함수 호출을 제한하는 데코레이터도 만들 수 있다.

def limit_calls_decorator(max_calls):
    def decorator(func):
        calls = 0

        def wrapper(*args, **kwargs):
            nonlocal calls
            if calls < max_calls:
                calls += 1
                return func(*args, **kwargs)
            else:
                raise Exception("함수 호출 횟수 초과")

        return wrapper

    return decorator

아래 실행 결과를 보면 3번째 실행할 때까지는 문제가 없었지만 그 이후는 예외가 발생한다.

예제 함수 실행
예제 함수 실행
예제 함수 실행
함수 호출 횟수 초과
함수 호출 횟수 초과
Traceback (most recent call last):
...

클래스 안에서도 데코레이터를 사용할 수 있다.

class TestExample:
    def _decorator(func):
        def wrap(self, *args, **kargs):
            print("Start", func.__name__)
            func(self, *args, **kargs)
            print("End", func.__name__)

        return wrap

    @_decorator
    def test(self, a, b, c):
        print("Variables :", a, b, c)

t = TestExample()
t.test("1", 2, c="345")


클래스를 사용해서도 데코레이터를 만들 수 있다.

아래는 함수가 호출될 때마다 count변수를 증가시킨다. 함수의 호출 횟수를 알 수 있다는 말이다.

class emoticon:
		def __init__(self, emoticon):
				self.count = 0# 호출 회수 저장 필드self.emoticon = emoticon

		def __call__(self, func):
				def inner(*args, **kwargs):
						self.count += 1
						inner.count = self.count# 함수 객체에서 바로 사용 할 수 있도록
						print(self.emoticon, ' ', end='')
						return func(*args, **kwargs)

				return inner

@emoticon('-_-')
def say_hi(name):
		print(f'hi {name}!')

say_hi('Jason')
print(say_hi.count)