콘텐츠로 건너뛰기

@decorator

장식물을 달아준다는 의미이다. 먼저 장식물이 없는 함수콜은 아래와 같다.일반 코드를 쓰면 아래와 같다.

def hello():
    print('hello~~')

hello()
-----------------------------------------------------------
hello~~

함수를 매개변수로 가지는 함수를 정의해서 윗 함수를 호출해보자

def test(func):
    print('인사의 시작')
    func()
    print('인사의 종료')

def hello():
    print('hello by normal function call')

test(hello)

이번엔 @데코레이터를 사용해보자.

def test(func):
    def wrapper():
        print('인사의 시작')
        func()
        print('인사의 종료')
    return wrapper

@test
def hello():
    print('hello by decorator')

hello()

사용법이 조금 복잡하다.

그래서 아래와 같이 설명을 적어서 이해해 보도록 노력했다.

def test(func): # 함수(hello)를 func라는 이름으로 받음
    def wrapper(): # func를 감쌀 '새로운 함수'를 정의
        print('인사의 시작') # 머릿글 추가
        func() # 여기서 진짜 hello()가 실행됨
        print('인사의 종료') #꼬릿글 추가
    return wrapper # 새로 만든 보자기(wrapper)를 반환

@test # 이제 아래에 정의되는 함수는 test라는 감옥에 갇힌다는 뜻임.
def hello():
    print('hello by decorator')

hello() # test라는 감옥에 갇힌 hello다.
# 그 결과: 인사 시작 -> hello -> 인사 종료

그럼 @데코레이터 이게 왜 좋은가?

  1. @데코레이터를 사용하면 hello()만 호출해도 됨. test(hello) 할 필요가 없음. 즉, hello의 성격이 바뀌었다.
  2. @데코레이터를 여러 함수에 적용할 수 있다. 게시판에 글을 쓰거나 수정하려면 로그인했느지 여부를 체크하는 루틴이 꼭 들어가야 하는데 이 때 글쓰기, 수정 함수를 정의 할 때, 정의 문 앞에 @login 이라는 데코레이터를 달아주면 post(), update() 함수를 그대로 사용할 수 있다.

@를 감옥이라고 표현한 이유

어린왕자를 보면 모자 형태를 보고 “코끼리를 삼킨 보아뱀”이라는 글이 있다. 본인은 @가 새장에 같힌 앵무새같이 보인다. 그래서 파이썬의 @데코레이터를 배울 때 함수를 새장과 같은 감옥에 가두는 느낌이 들었다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다