2008-11-11 6 views
9

나는 다른 누군가가 작성한 다소 복잡한 데코레이터가 있습니다. 내가하고 싶은 것은 descision을 기반으로 한 장식 된 버전의 함수를 호출하거나 다른 시간에 원래 함수 (데코 레이팅되지 않은)를 호출하는 것입니다. 이것이 가능한가?전화하기 전에 파이썬 함수를 장식하기

decorator(original_function)() 

없는 :와

답변

26

original_function() 

데코레이터는 인수로 함수를 취하고 다른 하나를 반환하는 함수이다. @ 구문은 전적으로 선택 사항입니다. 아마도 documentation을 살펴보면 상황을 명확히하는 데 도움이 될 것입니다.

+0

링크가 깨졌습니다. ( –

+0

링크가 고정되어 있습니다 :) – chishaku

2
def original_function(): 
    pass 

decorated_function= decorator(original_function) 

if use_decorated: 
    decorated_function() 
else: 
    original_function() 

한 번만 장식하고 나중에 전화 할 버전을 선택하십시오.

1

다음은 내가 문제를 생각해내는 조리법입니다. 또한 서명을 동일하게 유지해야 데코레이터 모듈을 사용했으나이를 방지하기 위해 다시 지그를 사용할 수있었습니다. 기본적으로, 속임수는 함수에 속성을 추가하는 것이 었습니다. '원래'함수는 언 바운드이므로 첫 번째 매개 변수로 'self'를 전달해야하므로 추가 코드를 추가하여이를 확인합니다.

# http://www.phyast.pitt.edu/~micheles/python/decorator-2.0.1.zip 
from decorator import decorator, update_wrapper 

class mustbe : pass 

def wrapper (interface_) : 
    print "inside hhh" 
    def call (func, self, *args, **kwargs) : 
     print "decorated" 
     print "calling %s.%s with args %s, %s" % (self, func.__name__, args, kwargs) 
     return interface_ (self, *args, **kwargs) 
    def original (instance , *args, **kwargs) : 
     if not isinstance (instance, mustbe) : 
      raise TypeError, "Only use this decorator on children of mustbe" 
     return interface_ (instance, *args, **kwargs) 
    call = decorator (call, interface_) 
    call.original = update_wrapper (original, call) 
    return call 

class CCC (mustbe): 
    var = "class var" 
    @wrapper 
    def foo (self, param) : 
     """foo""" 
     print self.var, param 

class SSS (CCC) : 
    @wrapper (hidden_=True) 
    def bar (self, a, b, c) : 
    print a, b, c 

if __name__ == "__main__" : 
    from inspect import getargspec 

    print ">>> i=CCC()" 
    i=CCC() 

    print ">>> i.var = 'parrot'" 
    i.var = 'parrot' 

    print ">>> i.foo.__doc__" 
    print i.foo.__doc__ 

    print ">>> getargspec(i.foo)" 
    print getargspec(i.foo) 

    print ">>> i.foo(99)" 
    i.foo(99) 

    print ">>> i.foo.original.__doc__" 
    print i.foo.original.__doc__ 

    print ">>> getargspec(i.foo.original)" 
    print getargspec(i.foo.original) 

    print ">>> i.foo.original(i,42)" 
    i.foo.original(i,42) 

    print ">>> j=SSS()" 
    j=SSS() 

    print ">>> j.bar(1,2,3)" 
    j.bar(1,2,3) 
관련 문제