可以这样写吗:
class Test(object):
def _decorator(self, foo):
foo()
@self._decorator
def bar(self):
pass
这个失败了:@self中的self是未知的
我还试过:
@Test._decorator(self)
同样失败:测试未知
我想暂时改变一些实例变量 在装饰器中再运行被装饰的方法 把它们换回来。
可以这样写吗:
class Test(object):
def _decorator(self, foo):
foo()
@self._decorator
def bar(self):
pass
这个失败了:@self中的self是未知的
我还试过:
@Test._decorator(self)
同样失败:测试未知
我想暂时改变一些实例变量 在装饰器中再运行被装饰的方法 把它们换回来。
当前回答
这是在同一个类中定义的装饰器中访问(并使用)self的一种方法:
class Thing(object):
def __init__(self, name):
self.name = name
def debug_name(function):
def debug_wrapper(*args):
self = args[0]
print 'self.name = ' + self.name
print 'running function {}()'.format(function.__name__)
function(*args)
print 'self.name = ' + self.name
return debug_wrapper
@debug_name
def set_name(self, new_name):
self.name = new_name
输出(在Python 2.7.10上测试):
>>> a = Thing('A')
>>> a.name
'A'
>>> a.set_name('B')
self.name = A
running function set_name()
self.name = B
>>> a.name
'B'
上面的例子很愚蠢,但它很有效。
其他回答
这是在同一个类中定义的装饰器中访问(并使用)self的一种方法:
class Thing(object):
def __init__(self, name):
self.name = name
def debug_name(function):
def debug_wrapper(*args):
self = args[0]
print 'self.name = ' + self.name
print 'running function {}()'.format(function.__name__)
function(*args)
print 'self.name = ' + self.name
return debug_wrapper
@debug_name
def set_name(self, new_name):
self.name = new_name
输出(在Python 2.7.10上测试):
>>> a = Thing('A')
>>> a.name
'A'
>>> a.set_name('B')
self.name = A
running function set_name()
self.name = B
>>> a.name
'B'
上面的例子很愚蠢,但它很有效。
我有一个可能有帮助的装饰器的实现
import functools
import datetime
class Decorator(object):
def __init__(self):
pass
def execution_time(func):
@functools.wraps(func)
def wrap(self, *args, **kwargs):
""" Wrapper Function """
start = datetime.datetime.now()
Tem = func(self, *args, **kwargs)
end = datetime.datetime.now()
print("Exection Time:{}".format(end-start))
return Tem
return wrap
class Test(Decorator):
def __init__(self):
self._MethodName = Test.funca.__name__
@Decorator.execution_time
def funca(self):
print("Running Function : {}".format(self._MethodName))
return True
if __name__ == "__main__":
obj = Test()
data = obj.funca()
print(data)
你可以装饰装饰器:
import decorator
class Test(object):
@decorator.decorator
def _decorator(foo, self):
foo(self)
@_decorator
def bar(self):
pass
import functools
class Example:
def wrapper(func):
@functools.wraps(func)
def wrap(self, *args, **kwargs):
print("inside wrap")
return func(self, *args, **kwargs)
return wrap
@wrapper
def method(self):
print("METHOD")
wrapper = staticmethod(wrapper)
e = Example()
e.method()
我在一些调试情况下使用这种类型的装饰器,它允许通过装饰来重写类属性,而不必找到调用函数。
class myclass(object):
def __init__(self):
self.property = "HELLO"
@adecorator(property="GOODBYE")
def method(self):
print self.property
下面是装饰器代码
class adecorator (object):
def __init__ (self, *args, **kwargs):
# store arguments passed to the decorator
self.args = args
self.kwargs = kwargs
def __call__(self, func):
def newf(*args, **kwargs):
#the 'self' for a method function is passed as args[0]
slf = args[0]
# replace and store the attributes
saved = {}
for k,v in self.kwargs.items():
if hasattr(slf, k):
saved[k] = getattr(slf,k)
setattr(slf, k, v)
# call the method
ret = func(*args, **kwargs)
#put things back
for k,v in saved.items():
setattr(slf, k, v)
return ret
newf.__doc__ = func.__doc__
return newf
注意:因为我使用了一个类装饰器,所以你需要使用@adecorator()来装饰函数,即使你没有向装饰器类构造函数传递任何参数。