>

클래스 메서드에 사용할 데코레이터를 만들 때 데코레이터 메커니즘이 함수/클로저가 아닌 클래스 인 경우 문제가 있습니다. 클래스 폼을 사용하면 데코레이터가 바인딩 된 메서드로 취급되지 않습니다.

일반적으로 데코레이터에 함수 형식을 사용하는 것을 선호하지만이 경우 기존 클래스를 사용하여 필요한 것을 구현해야합니다.

이것은 python-decorator-makes-function-forget-that-it-long-to-a-a-class 그러나 함수 형식에 적합한 이유는 무엇입니까?

다음은 모든 진행 상황을 보여줄 수있는 가장 간단한 예입니다. 코드 양에 대해 죄송합니다 :

def decorator1(dec_param):
    def decorator(function):
        print 'decorator1 decoratoring:', function
        def wrapper(*args):
            print 'wrapper(%s) dec_param=%s' % (args, dec_param)
            function(*args)
        return wrapper
    return decorator
class WrapperClass(object):
    def __init__(self, function, dec_param):
        print 'WrapperClass.__init__ function=%s dec_param=%s' % (function, dec_param)
        self.function = function
        self.dec_param = dec_param
    def __call__(self, *args):
        print 'WrapperClass.__call__(%s, %s) dec_param=%s' % (self, args, self.dec_param)
        self.function(*args)
def decorator2(dec_param):
    def decorator(function):
        print 'decorator2 decoratoring:', function
        return WrapperClass(function, dec_param)
    return decorator
class Test(object):
    @decorator1(dec_param=123)
    def member1(self, value=1):
        print 'Test.member1(%s, %s)' % (self, value)
    @decorator2(dec_param=456)
    def member2(self, value=2):
        print 'Test.member2(%s, %s)' % (self, value)
@decorator1(dec_param=123)
def free1(value=1):
    print 'free1(%s)' % (value)
@decorator2(dec_param=456)
def free2(value=2):
    print 'free2(%s)' % (value)
test = Test()
print '\n====member1===='
test.member1(11)
print '\n====member2===='
test.member2(22)
print '\n====free1===='
free1(11)
print '\n====free2===='
free2(22)

출력 :

decorator1 decoratoring: <function member1 at 0x3aba30>
decorator2 decoratoring: <function member2 at 0x3ab8b0>
WrapperClass.__init__ function=<function member2 at 0x3ab8b0> dec_param=456
decorator1 decoratoring: <function free1 at 0x3ab9f0>
decorator2 decoratoring: <function free2 at 0x3ab970>
WrapperClass.__init__ function=<function free2 at 0x3ab970> dec_param=456
====member1====
wrapper((<__main__.Test object at 0x3af5f0>, 11)) dec_param=123
Test.member1(<__main__.Test object at 0x3af5f0>, 11)
====member2====
WrapperClass.__call__(<__main__.WrapperClass object at 0x3af590>, (22,)) dec_param=456
Test.member2(22, 2)        <<<- Badness HERE!
====free1====
wrapper((11,)) dec_param=123
free1(11)
====free2====
WrapperClass.__call__(<__main__.WrapperClass object at 0x3af630>, (22,)) dec_param=456
free2(22)

  • 답변 # 1

    와이즈 비즈  (함수와 마찬가지로) 서술자이어야 함, 즉 적절한 특수 메소드를 제공하십시오.  그리고 WrapperClass . 이 방법 안내서는 그에 대해 알아야 할 모든 것을 가르쳐줍니다!-)

    __get__

관련 자료

  • 이전 크로스 플랫폼 Net?
  • 다음 MATLAB의 imagesc 플롯에 범례를 추가하는 방법