2014-03-24 3 views
0

다음 코드의 호출 순서에 혼란 스럽습니다.파이썬 장식 자의 호출 순서를 이해하는 방법

#/usr/bin/python 


def decorator_no_args(fn): 
    if not callable(fn): 
     raise TypeError 

    def wrapper(): 
     return fn() 

    print "decorator_no_args" 
    return wrapper 


@decorator_no_args 
def foo_no_args(): 
    print "foo_no_args" 


def decorator_args(* args, **kargs): 
    def wrapper0(fn): 
     def wrapper1(*args, **kargs): 
      return fn(*args, **kargs) 
     return wrapper1 

    print "decorator_args" 
    return wrapper0 


@decorator_args(1) 
def foo_args(arg0): 
    print "foo_args" 


if __name__ == "__main__": 
    foo_no_args() 

출력은 다음과 같습니다 위에서 볼 수 있듯이

decorator_no_args 
decorator_args 
foo_no_args 

기능 decorator_args()가 호출되지 않습니다. 그러나 왜 기록됩니까?

답변

1

2 가지 : 함수 정의가 실행될 때 장식 가인가되고, @expression 구가 소요; 장식 할 때 평가됩니다.

라인 @decorator_args(1)decorator_args() 함수를 호출하며 1을 인수로 전달합니다. 이 호출의 결과 인이 데코레이터로 사용됩니다. 라고

def foo_args(arg0): 
    print "foo_args" 
foo_args = decorator_args(1)(foo_args) 

decorator_args(1) 것을 :

@decorator_args(1) 
def foo_args(arg0): 
    print "foo_args" 

정말으로 실행됩니다

장식이, 정말 그냥 문법 설탕입니다. 반환 값은 이고 다시을 호출하여 장식 된 결과를 생성합니다.

당신이 decorator_args() 볼 때 당신이 데코레이터 반환 참조 :

def decorator_args(* args, **kargs): 
    def wrapper0(fn): 
     def wrapper1(*args, **kargs): 
      return fn(*args, **kargs) 
     return wrapper1 

    print "decorator_args" 
    return wrapper0 

wrapper0 진짜 장식입니다; decorator_args()이 호출되면 리턴됩니다. foo_args()wrapper0() (fn 인수)로 전달되며 원래 함수는 wrapper1으로 바뀝니다.

foo_args은 전혀 호출되지 않습니다. 데코레이터는 함수를 호출 할 때마다 적용되지 않고 한 번만 적용됩니다. foo_no_args() 번을 두 번 이상 호출하면 decorator_no_args 메시지가 반복되지 않습니다.

0

내가 기억한다면, 데코레이터는 본질적으로 인수로 함수를 사용하고 다른 함수를 반환하는 함수입니다. 그건 재미입니다.

는 출력합니다 (decorator_* 사람)의 처음 두 줄은 을 정의를 호출되지 되는 기능 foo_no_argsfoo_args에서 왔습니다.

def my_decorator(func): 
    def wrap(): 
     print "Function ran" 
     return func() 
    print "Function defined" 
    return wrap 

@my_decorator 
def my_function(): 
    print "my_function" 

my_function() 
my_function() 
my_function() 

출력 :

Function defined 
function ran 
my_function 
function ran 
my_function 
function ran 
my_function 

더 잘 이해하기 위해

이 조각에서 봐