当我尝试用decorate中的参数装饰一个方法时,它给我一个self
未定义。如果我改为将val
更改为类变量并使用MyCls.val
它现在给我MyCls未定义!我如何装饰我的mehtod?
def dodecorate(VAL):
def decorate(func):
def wrapped(*args,**kwargs):
res = func(*args,**kwargs)
if res == VAL:
res = "one"
return res
return wrapped
return decorate
class MyCls(object):
def __init__(self):
self.val = 1
@dodecorate(VAL = self.val)
def onefrom1(self, x):
return x
编辑以上是我发明的代表原作的抽象。这是实际的代码。
def retry_on_invalid_schema(MAX_RETRIES):
def retrier(func):
def wrapped(*args, **kwargs):
tries = 0
res = None
while tries < MAX_TRIES:
try:
res = func(*args, **kwargs)
assert res.has_key('by')
assert res.has_key('id')
break
except AssertionError:
res = None
time.sleep(2**tries)
tries += 1
continue
return res
return wrapped
return retrier
class Base(object):
def __init__(self):
self.MAX_RETRIES = 3
@retry_on_invalid_schema(MAX_RETRIES = self.MAX_RETRIES)
def _get_api_response(self, uri):
return json.loads(self._get(uri))
def _get(self, uri):
return requests.get(uri).text
答案 0 :(得分:1)
如果要在实例方法上使用现有的装饰器函数,请注意您可以在__init__
中重新定义实例方法,直接调用装饰器而不是使用@
语法:
class MyCls(object):
def __init__(self):
self.val = 1
self.onefrom1 = dodecorate(self.val)(self.onefrom1)
def onefrom1(self, x):
return x
使用中:
>>> a = MyCls()
>>> for x in range(3):
print a.onefrom1(x)
0
one
2
答案 1 :(得分:0)
您可以通过实例访问它,而不是尝试将val
传递给装饰器。 self
包含当前实例,并传递给装饰器中的wrapped方法,因此您可以在装饰器中将其作为第一个参数进行访问。
def decorate(func):
def wrapped(instance, *args, **kwargs):
res = func(instance, *args, **kwargs)
if res == instance.val:
res = "one"
return res
return wrapped
class MyCls(object):
def __init__(self):
self.val = 1
@decorate
def onefrom1(self, x):
return x
c = MyCls()
print c.onefrom1(1)
print c.onefrom1(2)
输出
one
2