개발일기

#9 파이썬 연습 (데코레이터) 본문

오늘의 공부일기/파이썬 공부일기

#9 파이썬 연습 (데코레이터)

츄98 2023. 3. 24. 16:10

데코레이터

이름 그대로 파이썬 함수를 장식해주는 역할
선언되는 함수 위에 골벵이를 사용해 @decorator 형태로 작성하며, 해당 함수가 실행될 때 데코레이터에서 선언된 코드가 같이 실행된다.

가장 큰 장점: 어떤 함수에도 데코레이터를 갖다 붙여주기만 하면 원하는 방식대로 코드를 실행시켜준다는 것!
# 데코레이터는 호출 할 함수를 인자로 받도록 선언한다.
def decorator(func):
    # 호출 할 함수를 감싸는 wrapper 함수를 선언한다.
    def wrapper():
        # func.__name__에는 데코레이터를 호출 한 함수의 이름이 들어간다.
        print(f"{func.__name__} 함수에서 데코레이터 호출")
        func()
        print(f"{func.__name__} 함수에서 데코레이터 끝")

    # wrapper 함수를 리턴한다.
    return wrapper
    
# 선언하는 함수 위에 @decorator를 추가해 데코레이터를 사용할 수 있다.    
@decorator
def decorator_func():
    print("decorator_func 함수 호출")

decorator_func()

# result output
"""
decorator_func 함수에서 데코레이터 호출
decorator_func 함수 호출
decorator_func 함수에서 데코레이터 끝
"""

 

데코레이터 작동원리

조금 더 자세히 살펴보자.
def wrapper_function(func):
	def decorated_function():
    	print("함수 이전에 실행")
        func()
        print("함수 이후에 실행")
    return decorated_function


@wrapper_function
def basic_function():
	print("실행하고자 하는 함수")

basic_function()

# 실행 결과

# 함수 이전에 실행
# 실행하고자 하는 함수
# 함수 이후에 실행

여기서

@wrapper_function
def basic_function():
print("실행하고자 하는 함수")

이것은,

new_function = wrapper_function(basic_function)
new_function()

이것과 같다.

 

 

데코레이터 활용하기

1)  mbti.py 앞서 만들었었던 함수인데.. 조금 바꿔보았다. 

def decorator(func):
    def wrapper():
        name = str(input("이름을 적어주세요."))
        mbti = str(input("mbti를 적어주세요."))
        func(name, mbti)

    return wrapper

@decorator
def you(name, mbti):
    a= name.strip()
    b= (mbti.strip()).upper()
    print(f'{a}의 mbti는 {b}이다.')

    result = ('지금 신나게 수다 떨면서 놀고 싶다. 혼자 있기 싫다.' if b[:1] == 'E'
              else '지금 집에 가고 싶다. 넷플릭스를 보며 혼자만의 시간을 갖고 싶다.')
    print(f'{a}님은 {result}')

you()

 

2) 어제 인바디검사를 하고 충격을 먹고..  BMI 지수를 측정해주는 함수를 만들어보았어요 ㅎㅎ

https://github.com/jisukim908/pythonpractice.git

 

GitHub - jisukim908/pythonpractice: Using python, make some interesting practices!

Using python, make some interesting practices! Contribute to jisukim908/pythonpractice development by creating an account on GitHub.

github.com

#표준체중(kg) = (현재신장cm - 100) X 0.9
#비만도(%) = (현재체중 ÷표준체중) X 100

def inbody_check(func):
    def wrapper():
        weight = int(input("당신의 몸무게를 입력하세요."))
        height = int(input("당신의 키를 입력하세요."))
        func(weight,height)

    return wrapper

@inbody_check
def bmi_test(weight, height):
    a = round((height - 100)*0.9,2)
    b = round((weight/a)*100,2)
    print(f'당신의 키를 기준으로 표준체중은 {a}kg이고, 당신의 비만도는 {b}%입니다.')
    if b<80:
        print("당신은 심각한 저체중입니다.")
    elif b<90:
        print("당신은 약한 저체중입니다.")
    elif b<110:
        print("당신은 장싱체중입니다.")
    elif b<120:
        print("당신은 과체중입니다.")
    elif b<130:
        print("당신은 경도비만입니다.")
    elif b<150:
        print("당신은 중증도비만입니다.")
    elif b<200:
        print("당신은 고도비만입니다.")
    else:
        print("당신은 위험한 비만입니다.")

bmi_test()

 

반복적으로 사용해야하는 코드 또는 부분이 있을 경우,

데코레이터를 사용하면 훨씬 편리하게 코드를 짤 수 있겠다는 생각을 데코레이터 연습하면서 느꼈습니다.

 

지금 제가 만든 함수들의 데코레이터를 보면.. 굳이 필요한 코드는 아닌 것 같다는 생각도 들어요.

데코레이터로 만들지 않고 함수에 같이 넣어도 문제없을 것 같다는 생각이 드는데..

만약에 자주 들어가는 코드나 부분이 있을 때에 데코레이터를 활용한다면 훨씬 코드도 짧아지고 유용하겠다는 생각을 했습니다. 이렇게 함수를 장식해주는 데코레이터에 대해서도 배워갑니다 :)