python 데코레이터(인자값 추가 설명 필요)

yuns_u·2021년 9월 29일
0

소개: 파이썬 데코레이터(@)

파이썬 데코레이터는 PEP318에서 어색하고 반복적인 함수의 표현을 줄이기 위해 제안되었다.
현재는 함수뿐만 아니라 클래스, 함수, 제너레이터 등의 다른 타입에서도 사용되고 있다.

  • 여러 타입에 데코레이터를 사용할 수 있는데 그 중 함수에서의 데코레이터가 가장 많이 사용되고 있다.
  • 이 포스트에서는 함수의 데코레이터 사용에 대해 살펴보고자 한다.
  • 서적(벌레책 등)에서 데코레이터를 찾아볼 때 'decoreated' 와 'wrapped'를 키워드로 많이 사용된다.

함수 데코레이터

간단한 문장 하나를 프린트하는 함수가 있는데 그 문장 전에 "first"라는 문장을 프린트하는 함수를 만든다면 아래처럼 만들 수 있을 것이다.

def practice():
    print("first")
    print("이것은 연습 함수입니다.")

만약 practice 함수와는 다른 함수가 "first"라는 문장을 프린트하고자한다면 동일하게 작성해주면 된다.

def practice():
    print("first")
    print("이것은 연습 함수입니다.")
    
def another_practice():
    print("first")
    print(이것은 다른 연습 함수입니다.)
    
def other_practice():
    print("first")
    print(이것은 전혀 다른 연습 함수입니다.)

위에서는 간단한 문장 하나를 프린트하기 때문에 큰 문제가 없지만 만약 복잡한 로직이 들어가게 된다면 함수가 복잡해질 수 있다. 만약 "first"를 10번 반복해서 출력한다면 10줄이 추가되거나 for 문을 사용해서 반복이 함수별로 들어갈 것이다.


데코레이터 기본 사용

데코레이터를 사용하면 이렇게 복잡한 것을 반복하지 않아도 된다.
먼저 위의 예제처럼 간단하게 "first"를 한 번 반복하는 함수를 데코레이터를 통해 표현하면 아래와 같다.

#이것이 데코레이터이다.
def first_deco(func): #func은 실행할 함수이다.
    def first(): 실행할 함수(func)를 감싸는(wrap) 함수이다.
        print("first")
        func()
    return first

#데코레이터로 아래의 별개의 함수들을 꾸며줄 수 있다.
@first_deco
def practice():
    print("이것은 연습 함수입니다.")
    
@first_deco
def another_practice():
    print(이것은 다른 연습 함수입니다.)

@first_deco
def other_practice():
    print(이것은 전혀 다른 연습 함수입니다.)

만약 "last"라는 문장을 각 함수의 마지막 출력된 값으로 만들고 싶다면 데코레이터를 조정해주면 된다.

def last_deco(func): #func은 실행할 함수이다.
    def last(): 실행할 함수(func)를 감싸는(wrap) 함수이다.
        func()
        print("last")
    return last

@last_deco
def practice():
    print("이것은 연습 함수입니다.")
    
@last_deco
def another_practice():
    print(이것은 다른 연습 함수입니다.)

@last_deco
def other_practice():
    print(이것은 전혀 다른 연습 함수입니다.)

첫 줄에 "first"를, 마지막 줄에 "last"를 출력하고자 한다면 마찬가지로 데코레이터를 조정해주면 된다.

def first_last_deco(func): #func은 실행할 함수이다.
    def first_last(): 실행할 함수(func)를 감싸는(wrap) 함수이다.
        print("first")
        func()
        print("last")
    return first_last

@first_last_deco
def practice():
    print("이것은 연습 함수입니다.")
    
@first_last_deco
def another_practice():
    print(이것은 다른 연습 함수입니다.)

@first_last_deco
def other_practice():
    print(이것은 전혀 다른 연습 함수입니다.)

데코레이터에 인자값을 처리하는 구문 넣기

❗️ 내가 사용할 함수에 인자가 주어진 경우에는 인자를 처리하는 구문이 작성되어야 정상적으로 작동한다.

아래의 you 함수는 작동하지 않는다.

def first_last_deco(func): # func 는 실행할 함수
    def first_last(): # 실행할 함수를 감싸는(wrap) 함수.
        print("first")
        func()
        print("last")
    return first_last

@first_last_deco
def you(name):
    print(f"{name}! Hello")

데코레이터를 적용하고자 하는 함수에 인자값이 정의되어 있을 때에는 데코레이터에도 인자값을 처리하는 구문인 *args, **kwargs 구문이 필요하다.
데코레이터에 인자값이 정의된 아래의 예시에서는 you 함수가 작동한다.

def first_last_deco(func): # func 는 실행할 함수
    def first_last(*args, **kwargs): # 실행할 함수를 감싸는(wrap) 함수.
        print("first")
        func(*args, **kwargs)
        print("last")
    return first_last

@first_last_deco
def you(name):
    print(f"{name}! Hello")

*args, **kwargs는 무엇인가?
*args, **kwargs는 함수의 인자와 어떤 관련이 있는가?


데코레이터를 사용하는 이유: DRY

DRY(Don't Repeat Yourself)

파이썬 개발자들이 유념하는 원칙 중에 코드의 반복 사용을 줄이기 위한 DRY원칙이 있다.
DRY원칙을 따르기 위해서 파이썬 개발자들은 상속, 디스크립터, 제너레이터 등 다양한 기술들을 사용하고 있다.
데코레이터 또한 코드의 반복적인 재사용을 줄이기 위한 기술이다.

데코레이터는 다양한 기술 주에서도 깔끔하고 간결한 코드를 만들면서 코드이 재사용을 줄이기 위해 많이 추천되는 기술이다. 그렇기 때문에 데코레이터를 해석하고 이해한다면 코드를 해석하는 데에 더 수월할 것이다.
또한 패키지를 이용할 때 데코레이터를 쉽게 마주할 수 있다.
예를 들어 딥러닝 텐서플로우의 @tensorflow.function처럼 마주할 수 있다.

@tensorflow.function
def calc(a, b):
    answer1 = a * b
    answer2 = a * b
    return answer1, answer2

데코레이터처럼 다양한 문법을 배우는 이유는 아래처럼 생각해볼 수 있다.

  • 다양한 패키지 사용자 입장에서 사용되는 기술을 알기 위해서
  • 파이썬 문법을 사용하는 것을 넘어 깨끗한(clean) 코드를 적기 위해서
profile
💛 공부 블로그 💛

0개의 댓글