데코레이터는 파이썬에서 함수 또는 메서드를 수정하지 않고도 추가 기능을 부여할 수 있는 강력한 기능입니다. 주로 코드의 재사용성, 유지보수성, 가독성을 높이는 데 사용됩니다. 데코레이터는 기존 함수에 기능을 "랩핑"하여 호출 전후로 특정 작업을 수행하도록 합니다.

1. 데코레이터의 기본 구조
데코레이터는 다른 함수를 인자로 받아 새로운 함수를 반환하는 함수로 정의됩니다.
def my_decorator(func): def wrapper(): print("함수 실행 전") func() print("함수 실행 후") return wrapper
설명: my_decorator 함수는 func를 받아 wrapper라는 새 함수를 반환합니다. wrapper는 func를 호출 전후에 추가 기능을 실행합니다.
2. 데코레이터 적용 방법
데코레이터는 함수 정의 위에 @데코레이터이름으로 적용합니다.
@my_decorator def say_hello(): print("Hello!") say_hello()
결과:
함수 실행 전 Hello! 함수 실행 후
설명: say_hello() 함수를 호출하면 @my_decorator 데코레이터가 적용되어 wrapper 함수가 실행됩니다. 따라서 say_hello() 함수는 "함수 실행 전", "Hello!", "함수 실행 후" 순으로 출력됩니다.
3. 인자를 받는 함수에 데코레이터 적용
인자를 받는 함수에 데코레이터를 적용하려면 *args와 **kwargs를 사용하여 모든 인자를 전달받도록 합니다.
def my_decorator(func): def wrapper(*args, **kwargs): print("함수 실행 전") result = func(*args, **kwargs) print("함수 실행 후") return result return wrapper @my_decorator def add(a, b): return a + b print(add(3, 5))
결과:
함수 실행 전 함수 실행 후 8
설명: add(3, 5) 호출 시, @my_decorator가 add 함수를 래핑하여 "함수 실행 전", "함수 실행 후"를 출력하고, 결과로 8을 반환합니다.
4. 여러 데코레이터 중첩 적용
여러 데코레이터를 중첩해서 적용할 수 있습니다. 데코레이터는 위에서 아래 순서로 적용됩니다.
def bold(func): def wrapper(*args, **kwargs): return "<b>" + func(*args, **kwargs) + "</b>" return wrapper def italic(func): def wrapper(*args, **kwargs): return "<i>" + func(*args, **kwargs) + "</i>" return wrapper @bold @italic def text(): return "Hello, World!" print(text())
결과:
<b><i>Hello, World!</i></b>
설명: @italic가 먼저 적용되어 <i>...</i>로 감싸지고, 그 다음 @bold가 적용되어 최종 출력이 <b><i>Hello, World!</i></b>로 반환됩니다.
5. 함수 실행 시간 측정 데코레이터 예제
데코레이터는 함수의 실행 시간을 측정하는 데 유용하게 사용될 수 있습니다.
import time def timer(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"실행 시간: {end_time - start_time:.4f}초") return result return wrapper @timer def slow_function(): time.sleep(2) print("작업 완료") slow_function()
결과:
작업 완료 실행 시간: 2.0003초
설명: @timer 데코레이터는 함수 실행 전후의 시간을 측정하고, slow_function()의 실행 시간을 출력합니다.
6. 접근 제어 데코레이터 (예: 로그인 필요)
특정 기능을 수행하기 전 사용자 인증이 필요할 때 데코레이터를 활용하여 접근 제어를 할 수 있습니다.
def requires_login(func): def wrapper(user, *args, **kwargs): if not user.get("is_logged_in"): print("로그인이 필요합니다.") return return func(user, *args, **kwargs) return wrapper @requires_login def view_profile(user): print(f"{user['name']}님의 프로필을 보여줍니다.") # 예제 사용자 user = {"name": "Alice", "is_logged_in": False} view_profile(user) # 결과: 로그인이 필요합니다. user["is_logged_in"] = True view_profile(user) # 결과: Alice님의 프로필을 보여줍니다.
설명: @requires_login 데코레이터는 user 딕셔너리의 is_logged_in 값이 True인지 확인하여, 로그인 여부에 따라 함수 실행을 제어합니다.
7. 클래스 메서드에 데코레이터 적용
데코레이터는 클래스 메서드에도 사용할 수 있습니다. 클래스 메서드나 정적 메서드에 데코레이터를 적용하려면 @classmethod나 @staticmethod와 함께 사용할 수 있습니다.
def log_method_call(func): def wrapper(*args, **kwargs): print(f"{func.__name__} 메서드가 호출되었습니다.") return func(*args, **kwargs) return wrapper class MyClass: @log_method_call def instance_method(self): print("인스턴스 메서드 실행") @classmethod @log_method_call def class_method(cls): print("클래스 메서드 실행") my_instance = MyClass() my_instance.instance_method() MyClass.class_method()
결과:
instance_method 메서드가 호출되었습니다. 인스턴스 메서드 실행 class_method 메서드가 호출되었습니다. 클래스 메서드 실행
설명: @log_method_call 데코레이터가 instance_method와 class_method 호출 시마다 실행되어, 메서드 호출을 로깅합니다.
8. 인자를 받는 데코레이터
데코레이터에 인자를 전달하려면, 데코레이터를 한 번 더 감싸는 함수를 사용합니다.
def repeat(n): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n): func(*args, **kwargs) return wrapper return decorator @repeat(3) def greet(): print("Hello!") greet()
결과:
Hello! Hello! Hello!
설명: @repeat(3) 데코레이터는 greet() 함수를 세 번 반복해서 호출하도록 만듭니다.
데코레이터는 코드의 재사용성과 유지보수성을 높여주며, 프로그램에 유연한 기능을 추가하는 데 매우 유용합니다.
'파이썬 Python' 카테고리의 다른 글
파이썬(Python) JSON 처리 (0) | 2024.11.26 |
---|---|
파이썬 Python 날짜와 시간 다루기 (0) | 2024.11.26 |
파이썬 Python 파일 경로 다루기 (0) | 2024.11.23 |
파이썬 Python 제너레이터와 이터레이터 사용하기 (0) | 2024.11.23 |
파이썬 Python 문자열 다루기 (0) | 2024.11.21 |
파이썬 Python 패키지 관리자 (pip) (0) | 2024.11.18 |
파이썬 Python 모듈과 라이브러리 사용하는 방법 (0) | 2024.11.18 |
파이썬 Python 파일 입출력 (File I/O) 사용하기 (1) | 2024.11.13 |
녹두장군1님의
글이 좋았다면 응원을 보내주세요!