functools.wraps에 대해

python 2015. 4. 15. 16:52

functools.wraps는 보통 python fucntion을 wrapping할 때 원래 function의 정보들을 유지 시키기 위해서 사용된다.

간단한 wrapper 코드를 보자.


import functools


def print_iam_wrapper(method):

    @functools.wraps(method)        ----- 1

    def wrapper(*args, **kwargs):    ----- 2

        print "I'm wrapper"

        return method(*args, **kwargs)


    return wrapper


@print_iam_wrapper

def iam_func():

    print 'iam_func'


print iam_func.__name__                  ----- 3 

iam_func()                                       ----- 4


여기서 1번을 제거해도 4번의 결과는 같다. 하지만 3번의 결과는 다르다.

wraps가 하는 일은 wraps, update_wrapper, partial 코드를 살펴보면 이해가 간다.

(3개의 function에 대한 코드는 아래에 두겠다.)

1번 decorator가 실행될때 method가 넘어가서 넘어오는 것은 결국 wraps의 결과인 partial() 리턴값인데 이것은 newfunc 이다. 그렇다면 1번은 @newfunc가 되었다고 볼 수 있다.


그리고 @newfunc에 파라미터로 넘어가는 것은 아래있는 wrapper function이 된다. 이때 newfunc은 update_wrapper를 실행하고 있으므로 이는 또한 @update_wrapper와 같다. 다만 이때 wrapped로 처음에 전달된 method 즉 iam_func이 넘어가 있을 것이다. 결국 의미는 wrapped에 설정되어있는 '__module__', '__name__', '__doc__', '__dict__' attritbute를 wrapper에 셋팅하여 던져주는 것이다.



* 참고) update_wrapper, wraps, partial

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')

WRAPPER_UPDATES = ('__dict__',)

def update_wrapper(wrapper,

                   wrapped,

                   assigned = WRAPPER_ASSIGNMENTS,

                   updated = WRAPPER_UPDATES):

    for attr in assigned:

        setattr(wrapper, attr, getattr(wrapped, attr))

    for attr in updated:

        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))

    # Return the wrapper so this can be used as a decorator via partial()

    return wrapper


def wraps(wrapped,

          assigned = WRAPPER_ASSIGNMENTS,

          updated = WRAPPER_UPDATES):


    return partial(update_wrapper, wrapped=wrapped,

                   assigned=assigned, updated=updated) 


def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc























'python' 카테고리의 다른 글

gunicorn vs uwsgi  (0) 2017.01.20
flask async response  (0) 2017.01.04
Apple Push Notification Service(APNs) python modules  (0) 2015.04.07
Getting specific timezone timestamp from time string  (0) 2015.01.20
Shallow copy VS Deep copy  (0) 2014.08.27
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,