클래스 인스턴스 변수를 파이썬의 메소드 데코레이터에 대한 인수로 어떻게 사용할 수 있습니까?
문제
클래스 인스턴스 변수를 파이썬의 메소드 데코레이터에 대한 인수로 어떻게 사용할 수 있습니까? 다음은 내가하려는 일을 보여주는 최소한의 예입니다. 데코레이터 함수가 인스턴스에 대한 참조에 액세스 할 수 없기 때문에 분명히 실패하며 데코레이터에서 참조에 액세스하는 방법을 모릅니다.
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
성명.
그렇습니다. 그러나 마법도 포함되지 않습니다.
제휴하지 않습니다 StackOverflow