python 에서 데코레이터
연결 문서
python 에서 데코레이터
데코레이터란 무엇인가?
데코레이터는 함수에 새로운 기능을 추가하는 도구임. 마치 선물을 포장지로 감싸는 것처럼, 함수에 데코레이터를 적용하면 그 함수에 부가적인 기능을 덧붙일 수 있음.
왜 데코레이터를 사용할까?
- 코드 재사용성 증가: 반복되는 코드를 줄일 수 있음.
- 코드 가독성 향상: 핵심 기능과 부가 기능을 분리하여 코드가 깔끔해짐.
- 유지 보수 용이: 한 곳에서 부가 기능을 관리할 수 있어 수정이 쉬워짐.
데코레이터를 현실에 비유하기 : 카페에서 주문하기
데코레이터를 이해하기 어려울 수 있으니, 현실적인 예로 비유해보겠음.
- 당신이 커피를 주문한다고 가정해보겠음.
- 기본적으로 커피는 에스프레소 샷으로 만들어짐.
- 여기에 시럽 추가나 휘핑크림 추가 등의 옵션을 더할 수 있음.
여기서 에스프레소는 기본 함수이고, 시럽 추가나 휘핑크림 추가는 데코레이터와 같음.
간단한 예제로 이해하기
예제 1 : 카페에서 주문하기
기본 함수 만들기
def 커피():
return "에스프레소"
커피()
함수를 호출하면 “에스프레소”를 반환함.
시럽 추가 데코레이터 만들기
def 시럽_추가(함수):
def wrapper():
결과 = 함수()
return 결과 + " + 시럽"
return wrapper
시럽_추가
데코레이터는 커피에 시럽을 추가함.
휘핑크림 추가 데코레이터 만들기
def 휘핑크림_추가(함수):
def wrapper():
결과 = 함수()
return 결과 + " + 휘핑크림"
return wrapper
휘핑크림_추가
데코레이터는 커피에 휘핑크림을 추가함.
데코레이터 적용하기
@시럽_추가
def 커피():
return "에스프레소"
이렇게 하면 커피()
함수를 호출할 때 시럽이 추가됨.
결과 확인하기
주문 = 커피()
print(주문)
출력:
에스프레소 + 시럽
여러 데코레이터 적용하기
데코레이터는 여러 개를 적용할 수 있음.
@휘핑크림_추가
@시럽_추가
def 커피():
return "에스프레소"
이렇게 하면 커피()
함수에 시럽과 휘핑크림이 모두 추가됨.
결과 확인하기
주문 = 커피()
print(주문)
출력:
에스프레소 + 시럽 + 휘핑크림
예제 2 : 간단한 인사하기
기본 함수 만들기
def 인사():
print("안녕하세요!")
인사()
함수를 호출하면 “안녕하세요!”가 출력됨.
함수에 부가 기능 추가하기 (데코레이터 없이)
함수가 호출될 때마다 로그를 출력하고 싶음.
def 인사():
print("인사 함수가 호출되었음")
print("안녕하세요!")
하지만 이런 방식은 함수마다 코드를 추가해야 해서 비효율적임.
데코레이터 만들기
def 로그_데코레이터(함수):
def wrapper():
print(f"{함수.__name__} 함수가 호출되었음")
함수()
return wrapper
로그_데코레이터
는 함수 호출 전에 로그를 출력해주는 데코레이터임.
데코레이터 적용하기
@로그_데코레이터
def 인사():
print("안녕하세요!")
@로그_데코레이터
를 사용하여 인사
함수에 로그 기능을 추가했음.
결과 확인하기
인사()
출력:
인사 함수가 호출되었음
안녕하세요!
함수 내부 코드를 수정하지 않고도 로그 기능을 추가했음.
조금 더 복잡한 예제 : 실행 시간 측정
실행 시간 측정 데코레이터 만들기
import time
def 실행시간_데코레이터(함수):
def wrapper():
시작시간 = time.time()
함수()
종료시간 = time.time()
print(f"실행 시간: {종료시간 - 시작시간}초")
return wrapper
데코레이터 적용하기
@실행시간_데코레이터
def 느린_함수():
time.sleep(2)
print("작업 완료!")
결과 확인하기
느린_함수()
출력:
작업 완료!
실행 시간: 2.002초
함수의 실행 시간을 자동으로 측정해줌.
또 다른 예제: 로그인 확인 데코레이터
웹 애플리케이션에서 사용자 로그인 여부를 확인하는 기능을 데코레이터로 만들어보겠음.
로그인 확인 데코레이터 만들기
def 로그인_확인(함수):
def wrapper(user):
if not user['로그인']:
print("로그인이 필요합니다.")
return
return 함수(user)
return wrapper
데코레이터 적용하기
@로그인_확인
def 프로필_보기(user):
print(f"{user['이름']}님의 프로필입니다.")
사용자 데이터 예시
사용자1 = {'이름': '철수', '로그인': True}
사용자2 = {'이름': '영희', '로그인': False}
결과 확인하기
프로필_보기(사용자1)
# 출력: 철수님의 프로필입니다.
프로필_보기(사용자2)
# 출력: 로그인이 필요합니다.
프로필_보기
함수를 호출할 때 로그인 여부를 자동으로 확인함.
데코레이터의 동작 원리 이해하기
데코레이터는 함수를 입력으로 받아 또 다른 함수를 반환하는 함수임.
데코레이터 함수 구조
def 데코레이터(함수):
def wrapper():
# 부가 기능 추가
결과 = 함수()
# 부가 기능 추가
return 결과
return wrapper
-
데코레이터
함수는함수
를 입력으로 받음. -
wrapper
함수 안에서 원본 함수를 호출하고 결과를 반환함. -
데코레이터
함수는wrapper
함수를 반환함.
데코레이터 적용 과정
@데코레이터
def 원본_함수():
pass
이 코드는 다음과 동일함.
def 원본_함수():
pass
원본_함수 = 데코레이터(원본_함수)
즉, 원본 함수가 데코레이터 함수에 의해 감싸여서 새로운 함수로 대체됨.
여러 인자를 가진 함수에 데코레이터 적용하기
인자를 가진 함수에도 데코레이터를 적용하려면 *args
와 **kwargs
를 사용하면 됨.
데코레이터 수정하기
def 로그_데코레이터(함수):
def wrapper(*args, **kwargs):
print(f"{함수.__name__} 함수가 호출되었음")
return 함수(*args, **kwargs)
return wrapper
인자를 가진 함수에 적용하기
@로그_데코레이터
def 덧셈(a, b):
return a + b
결과 = 덧셈(3, 5)
print(f"결과: {결과}")
출력:
덧셈 함수가 호출되었음
결과: 8
정리하며
- 데코레이터는 함수에 부가적인 기능을 쉽게 추가할 수 있게 해주는 도구임.
-
@데코레이터_이름
을 사용하여 간단하게 적용할 수 있음. - 부가 기능을 별도의 함수로 분리하여 코드의 재사용성과 가독성을 높일 수 있음.
마치며
처음에는 데코레이터가 어려워 보일 수 있지만, 예제를 따라 해보면서 이해하면 큰 도움이 될 것임. 직접 다양한 데코레이터를 만들어보고 적용해보면서 파이썬의 강력한 기능을 활용해보길 바람.
Enjoy Reading This Article?
Here are some more articles you might like to read next: