클래스 인스턴스 변수를 파이썬의 메소드 데코레이터에 대한 인수로 어떻게 사용할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1231950

  •  22-07-2019
  •  | 
  •  

문제

클래스 인스턴스 변수를 파이썬의 메소드 데코레이터에 대한 인수로 어떻게 사용할 수 있습니까? 다음은 내가하려는 일을 보여주는 최소한의 예입니다. 데코레이터 함수가 인스턴스에 대한 참조에 액세스 할 수 없기 때문에 분명히 실패하며 데코레이터에서 참조에 액세스하는 방법을 모릅니다.

def decorator1(arg1):
    def wrapper(function):
        print "decorator argument: %s" % arg1
        return function
    return wrapper

class Foo(object):
    def __init__(self, arg1):
        self.var1 = arg1

    @decorator1(self.var1)
    def method1(self):
        print "method1"

foo = Foo("abc")
foo.method1()
도움이 되었습니까?

해결책

작동하지 않을 것입니다. 데코레이터는 그 동안 호출됩니다 수업 창출 인스턴스가 생성되기 오래 전인 시간 (만약에 그럴 때). 따라서 "데코레이터"가 인스턴스가 필요한 경우 인스턴스화 시간에 "장식"을해야합니다.

def get_decorator(arg1):
    def my_decorator(function):
        print "get_decorator argument: %s" % arg1
        return function
    return my_decorator

class Foo(object):
    def __init__(self, arg1):
        self.var1 = arg1
        self.method1 = get_decorator(self.var1)(self.method1)

    def method1(self):
        print "method1"

foo = Foo("abc")
foo.method1()

그들의 의미에 따라 함수 이름을 변경했습니다. 실제 "데코레이터", 즉 (잠재적으로) 방법을 수정하는 기능은 다음과 같습니다. wrapper 귀하의 경우에는 그렇지 않습니다 decorator1.

다른 팁

"워퍼"기능은 실제로 워퍼가 아닌 데코레이터입니다. "Decorator1"기능은 데코레이터 생성자입니다. 런타임에 self.var1에 액세스하려면 데코레이터가 아닌 워퍼를 만들어야합니다.

def decorator(function):
  def wrapper(self,*args,**kwargs):
    print "Doing something with self.var1==%s" % self.var1
    return function(self,*args,**kwargs)
  return wrapper

class Foo(object):
  def __init__(self, arg1):
    self.var1 = arg1

  @decorator
  def method1(self):
    print "method1"

foo = Foo("abc")
foo.method1()

더 일반적인 데코레이터를 원한다면 전화 가능한 클래스를 선언하는 것이 좋습니다.

class decorator:
  def __init__(self,varname):
      self.varname = varname
  def __call__(self,function):
    varname=self.varname
    def wrapper(self,*args,**kwargs):
      print "Doing something with self.%s==%s" % (varname,getattr(self,varname))
      return function(self,*args,**kwargs)
    return wrapper

사용 :

  @decorator("var1")

데코레이터는 클래스가 정의 될 때 실행되므로 인스턴스 변수를 전달할 수 없습니다.

우리가 옛날 에이 작업을 수행했던 방법은 다음과 같습니다.

class Foo(object):
    def __init__(self, arg1):
        self.var1 = arg1

    def method1(self):
        self.lock()
        try:
            self.do_method1()
        except Exception:
            pass # Might want to log this
        finally:
            self.unlock()

    def do_method1(self):
        print "method1"

    def lock(self):
        print "locking: %s" % self.arg1

    def unlock(self):
        print "unlocking: %s" % self.arg1

이제 서브 클래스는 O 재정의 만 있으면됩니다 do_method1 "포장"의 이점을 얻으려면. 아무 것도없이 오래된 방식으로 끝났습니다 with 성명.

그렇습니다. 그러나 마법도 포함되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top