可以这样写吗:
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)
同样失败:测试未知
我想暂时改变一些实例变量 在装饰器中再运行被装饰的方法 把它们换回来。
当前回答
装饰器似乎更适合修改整个对象(包括函数对象)的功能,而不是对象方法的功能,后者通常依赖于实例属性。例如:
def mod_bar(cls):
# returns modified class
def decorate(fcn):
# returns decorated function
def new_fcn(self):
print self.start_str
print fcn(self)
print self.end_str
return new_fcn
cls.bar = decorate(cls.bar)
return cls
@mod_bar
class Test(object):
def __init__(self):
self.start_str = "starting dec"
self.end_str = "ending dec"
def bar(self):
return "bar"
输出结果为:
>>> import Test
>>> a = Test()
>>> a.bar()
starting dec
bar
ending dec
其他回答
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()
装饰器似乎更适合修改整个对象(包括函数对象)的功能,而不是对象方法的功能,后者通常依赖于实例属性。例如:
def mod_bar(cls):
# returns modified class
def decorate(fcn):
# returns decorated function
def new_fcn(self):
print self.start_str
print fcn(self)
print self.end_str
return new_fcn
cls.bar = decorate(cls.bar)
return cls
@mod_bar
class Test(object):
def __init__(self):
self.start_str = "starting dec"
self.end_str = "ending dec"
def bar(self):
return "bar"
输出结果为:
>>> import Test
>>> a = Test()
>>> a.bar()
starting dec
bar
ending dec
在内部类中声明。 这个解决方案非常可靠,值得推荐。
class Test(object):
class Decorators(object):
@staticmethod
def decorator(foo):
def magic(self, *args, **kwargs) :
print("start magic")
foo(self, *args, **kwargs)
print("end magic")
return magic
@Decorators.decorator
def bar( self ) :
print("normal call")
test = Test()
test.bar()
结果:
>>> test = Test()
>>> test.bar()
start magic
normal call
end magic
>>>
你想做的事是不可能的。例如,下面的代码看起来是否有效:
class Test(object):
def _decorator(self, foo):
foo()
def bar(self):
pass
bar = self._decorator(bar)
当然,它是无效的,因为self在那一点上没有定义。Test也是一样,因为直到类本身被定义(它正在定义过程中),它才会被定义。我向您展示这个代码片段是因为这是您的装饰器片段转换成的内容。
因此,如您所见,在这样的装饰器中访问实例实际上是不可能的,因为装饰器是在它们所附加的任何函数/方法的定义期间应用的,而不是在实例化期间。
如果你需要类级访问,试试这个:
class Test(object):
@classmethod
def _decorator(cls, foo):
foo()
def bar(self):
pass
Test.bar = Test._decorator(Test.bar)
我有一个可能有帮助的装饰器的实现
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)