Python - Decorator

노광오·2020년 7월 25일

Python

목록 보기
12/13

데코레이터(Decorator)

데코레이터란 무엇일까요? 사전적 의미로는 "장식가" 또는 "인테리어 디자이너" 등의 의미를 가지고 있습니다. 이름 그대로, 자신의 방을 예쁜 벽지나 커튼으로 장식을 하듯이, 기존의 코드에 여러가지 기능을 추가하는 파이썬 구문이라고 생각하시면 됩니다.

데코레이터를 이해하려면 다음과 같은 내용을 이해해야 한다.

  • 클로저
  • 함수를 일급 인자(first-class argument)로 활용하는 법
  • 가변 인자
  • 인자 풀기(argument unpacking)
  • 파이썬이 소스코드를 불러오는 자세한 과정

클로저(Closure)

클로저는 일반 함수와 다르게, 자신의 영역 밖에서 호출된 함수의 변수값과 레퍼런스를 복사, 저장, 접근을 가능하게 한다.

예시

def say_words(msg):
    def say_sentence():
        return "안녕? 이걸 출력해줘! : {}".format(msg)
    return say_sentence
 
a = say_words("출출하다")
print("a는 무엇일까? : ", a)
print("a의 타입은 무엇일까? : ", type(a))
print("a가 함수라는 걸 알았다. 괄호를 붙여보자. ====> ", a())

출력 결과

>>> a는 무엇일까? :  <function say_words.<locals>.say_sentence at 0x7fc2c039c0d0>
>>> a의 타입은 무엇일까? :  <class 'function'>
>>> a가 함수라는 걸 알았다. 괄호를 붙여보자. ====>  안녕? 이걸 출력해줘! : 출출하다

특징

클로저는 바깥 함수로부터 생성된 변수를 어딘가에 저장한다. 그리고 이를 기억하고 있는다.
함수가 종료되도 클로저 함수가 기억하고 있는 변수는 메모리상에서 사라지지 않는다.

결론

클로저는 다른 함수에 의해 동적으로 생성되고, 바깥 함수로부터 생성된 변수값을 알고 있는 변수이다.

일등 함수(first-class citizen)

퍼스트클래스 함수란 프로그래밍 언어가 함수(function) 를 first-class citizen으로 취급하는 것을 뜻합니다. 쉽게 설명하자면 함수 자체를 인자(argument) 로써 다른 함수에 전달하거나 다른 함수의 결과값으로 리턴 할수도 있고, 함수를 변수에 할당하거나 데이터 구조안에 저장할 수 있는 함수를 뜻합니다.

일등 시민(first-class citizen) 이라는 것은 정말 생소한 개념이다.
익숙하진 않지만, 다음 조건을 충족한다면 일등 시민이라고 할 수 있다.

  • 변수나 데이터에 할당 할 수 있어야 한다.
  • 객체의 인자로 넘길 수 있어야 한다.
  • 객체의 리턴값으로 리턴 할 수 있어야 한다.

일급 객체

컴퓨터 프로그래밍 언어 디자인에서, 일급 객체(first-class object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 함수에 매개변수로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원할 때 일급 객체라고 한다.

파이썬에서는 독특하게도 함수도 위와 같은 기능을 수행한다.

이러한 특징을 가진 일급 객체(first-class citizen)를 사용하면 손쉽게 함수를 재활용 할 수 있다.

Decorator 개념

데코레이터(Decorator)는 하나의 함수를 취해서 또 다른 함수를 반환하는 함수이다.

데코레이터 예제

def decorator_function(original_function): #1, #4 
    def wrapper_function(): #5 #8 
        return original_function() #9 
    return wrapper_function #6 
 
def display(): #2, #10 
    print("display 함수가 실행됐습니다") #11 
 
decorated_display = decorator_function(display)  #3 display 함수를 전달 
decorated_display() #7 
  1. #3: decorated_display라는 변수는 decorated_function 함수의 리턴값을 할당받는다.

  2. #6: return값은 wrapper_function이라는 함수다.

  3. 변수는 결국 함수를 실행시킬 수 있는 함수다.

  4. #7: 변수가 함수니까 괄호를 붙여 실행시켜보자.

  5. #8, #9 : return 값으로 original_function을 돌려준다.

  • 여기서 closure 함수의 개념이 쓰인다.
  • 바깥 함수(decorator_function)에서 전달받은 original_function을 기억하고 있다.
  1. #10, #11 : 여기서 비로소 함수를 실행하고, print문을 실행한다.

데코레이터를 쓰는 상황

  1. 로그를 남길때
  2. 유저의 로그인 상태를 확인하여 로그인 페이지로 redirect할 때
  3. 프로그램 성능을 위한 테스트를 할 때

0개의 댓글