decorator

BackEnd_Ash.log·2020년 2월 15일
0

파이썬

목록 보기
3/34

📌Decorator 란 무엇인가 ?

파이썬은 데코레이터라는 기능을 제공한다.

데코레이터는 말 그대로 장식이라는 뜻을 가지고 있다.

함수 위에 @ 로 시작하는것이 데코레이터 이다.

decorator 란 무엇이며 언제 왜 사용하는것일까 ?

def jackpot_stock_information():
    return "계시가 내려졌습니다. 삼성전자를 사세요!"

이 주식정보는 유료회원만 받을 수 있다.

그래서 이 함수가 호출 되기 전에 해당 유저가 유료회원인지를 확인해야 한다.

그리고 해당 유저가 유로 회원인지 확인 해주는 함수는 다음과 같다 .

일단은 모든 유저가 유료 회원이라고 가정을 해본다.


def is_paid_user():
    return True

jackpot_stock_information 함수가 호출되기 전에 is_paid_user 함수가 호출되어야 확인이 가능하다.

if is_paid_user():
    jackpot_stock_information()

이렇게 is_paid_user 함수 상단에 jackpot_stock_infomation() 를 호출하게 되면 문제가 없어 보인다.

하지만 만약에 다른곳에서 사용을 해야한다면 ??

jackpot_stock_information 함수가 호출 될때 is_paid_user 가 무조건 먼저 되어야 하는데 , 그럼

jackpot_stock_information 함수를 호출할때 마다 똑같이 is_paid_user 함수를 호출해야한다.

그래서 jackpot_stock_information 함수를 호출할 때 알아서 자동으로 is_paid_user 함수가 강제적

으로 먼저 호출되게 할 수 있는 방법이 없을까 ?? 라는 생각이 들었다. ==> decorator

👉decorator 는 어떻게 사용하는걸까 ??

@is_paid_user
def jackpot_stock_information():
    return "계시가 내려졌습니다. 삼성전자를 사세요!"

위의 골뱅이로 장식 을 해주면 된다.

jackpot_stock_information 함수가 호출되기 전에
is_paid_user 함수가 호출하게 된다.

그렇다면 아무함수에 다 decorator 를 달아버리면 되지않나 ??
그렇게는 안됩니다.

decorator로 장식할 수 있는 함수는 중첩 함수 (nested function)을 리턴하는 함수만 decorator 함수로 사용 될 수 있다.

decorator 함수의 기능을 다르게 설명하면 chain of functions 라고 설명할 수 있다.
여러개의 함수가 연속적으로 호출이 자동으로 되게 해주는것이다.

그럴려면 마지막 함수를 제외한 함수들은 그 다음 함수를 리턴해줘야 파이썬이 함수들을 차례대로 호출 해줄수 있겠지 ??
(만일 다음 함수를 리턴하지 않고 다른 값을 리턴해버리면 그다음 함수로 넘어가지 못하고 그냥 함수 실행이 종료된다 )

위 그림처럼 마지막 함수를 제외한 함수들은 그다음 함수를 리턴을 해줘야한다.

def is_paid_user(func):
    user_paid = True  # 간단화 하기 위해 무조건 True

    def wrapper(*args, **kwargs):
        if user_paid:
            return func()
        else:
            return

    return wrapper


@is_paid_user
def jackpot_stock_information():
    return "계시가 내려졌습니다. 삼성전자를 사세요!"

print(jackpot_stock_information())

📌👉

📌코딩도장 참고 decoratr

https://dojang.io/mod/page/view.php?id=2428

위는 매개변수가 없이 데코레이터를 만들었다면 ,

지금부터는 매개변수반환값 을 처리하는 데코레이터를 보기로 한다.

👉 매개변수 와 반환값 처리 데코레이터

def trace(func):
    def wrapper(a,b):
        r = func(a,b)
        print(f'{func.__name__} , {a} , {b}')
        return r
    return wrapper

@trace
def add(a,b):
    return a+b
print(add(10,20))

👉 가변 인수 처리 데코레이터

위의 코드 def add(a,b): 는 매개변수의 개수가 고정된 함수이다.

매개변수(인수)가 고정되지 않은 함수는 어떻게 처리할까?

wrapper 함수를 가변 인수 함수로 만든다.

def trace(func):                     # 호출할 함수를 매개변수로 받음
    def wrapper(*args, **kwargs):    # 가변 인수 함수로 만듦
        r = func(*args, **kwargs)    # func에 args, kwargs를 언패킹하여 넣어줌
        print('{0}(args={1}, kwargs={2}) -> {3}'.format(func.__name__, args, kwargs, r))
                                     # 매개변수와 반환값 출력
        return r                     # func의 반환값을 반환
    return wrapper                   # wrapper 함수 반환
 
@trace                   # @데코레이터
def get_max(*args):      # 위치 인수를 사용하는 가변 인수 함수
    return max(args)
 
@trace                   # @데코레이터
def get_min(**kwargs):   # 키워드 인수를 사용하는 가변 인수 함수
    return min(kwargs.values())
 
print(get_max(10, 20))
print(get_min(x=10, y=20, z=30))

profile
꾸준함이란 ... ?

0개의 댓글