2012-09-11 4 views
3

어렵습니다. 나는 메소드를 동적으로 생성 할뿐만 아니라 데코레이터를 연관시키고 자한다. 이것은 내가 출력은데코레이터로 동적 메서드 생성하기

import inspect 
import types 

class Dynamo(object): 
    pass 

def call_me_dec(func): 
    print 'I am here' 
    return func 

def add_dynamo(cls,i): 
    # @call_me_dec 
    def innerdynamo(self): 
     print "in dynamo %d" % i 
     return i 

    innerdynamo.__doc__ = "docstring for dynamo%d" % i 
    innerdynamo.__name__ = "dynamo%d" % i 
    setattr(cls, innerdynamo.__name__, innerdynamo) 

def add_decorators(cls): 
    for name, fn in inspect.getmembers(cls): 
     if isinstance(fn, types.UnboundMethodType): 
      setattr(cls, name, call_me_dec(fn)) 

for i in range(2): 
    add_dynamo(Dynamo, i) 

add_decorators(Dynamo) 

d=Dynamo() 
d.dynamo0() 
d.dynamo1() 

뭘하려 :

I am here 
    I am here 
    in dynamo 0 
    in dynamo 1 

예상 출력 :

I am here 
    in dynamo 0 
    I am here 
    in dynamo 1 

설명해주십시오 왜 이런 일이 어떻게 내가 원하는 결과를 얻을 수 있나요?

답변

5

데코레이터 코드가 데코 레이팅 된 함수를 만들 때 호출되었으므로, 함수가 호출 될 때가 아닙니다. 코드를 호출하여 실행하려면 데코레이터가 데코 레이팅 된 메서드를 호출하는 호출 가능 객체 (일반적으로 클로저)를 반환하도록해야합니다. 예는 :

def call_me_dec(func): 
    print 'Decorating %s' % func 
    def func_wrapper(*args, **kwargs): 
     print 'Calling %s' % func 
     return func(*args, **kwargs) 
    return func_wrapper 

데코레이터 구문은 구문 설탕입니다. 주의 사항 :

def func(): 
    pass 
func = deco(func) 

@deco 
def func(): 
    pass 

어느 쪽이든에 해당합니다, 당신은 명시 적으로 deco 정의 func 전달에서 반환 된 객체를 참조하는 로컬 네임 스페이스의 func 레이블 끝. 데코레이터 구문은 번들을 추가로 묶어 놓는다. (예 : deco의 입력과 출력이 항상 호출 가능함을 확인하는 것과 같다.) 기본적으로 예제 1에서 주어진 방식대로 작동하면 예제 2에서 그런 식으로 작동한다.