如果我有一个功能:
@aDecorator def myfunc1(): # do something here if __name__ = "__main__": # this will call the function and will use the decorator @aDecorator myfunc1() # now I want the @aDecorator to be replaced with the decorator @otherDecorator # so that when this code executes, the function no longer goes through # @aDecorator, but instead through @otherDecorator. How can I do this? myfunc1()
是否可以在运行时替换装饰器?
正如Miya所提到的,在解释器获得该函数声明之前,您可以在任何点上用另一个函数替换装饰器.但是,一旦将装饰器应用于该函数,我认为没有办法用另一个动态替换装饰器.例如:
@aDecorator def myfunc1(): pass # Oops! I didn't want that decorator after all! myfunc1 = bDecorator(myfunc1)
不起作用,因为myfunc1不再是你最初定义的函数; 它已被包裹.这里最好的方法是手动应用装饰器,oldskool-style,即:
def myfunc1(): pass myfunc2 = aDecorator(myfunc1) myfunc3 = bDecorator(myfunc1)
编辑:或者,要更清楚一点,
def _tempFunc(): pass myfunc1 = aDecorator(_tempFunc) myfunc1() myfunc1 = bDecorator(_tempFunc) myfunc1()
我不知道是否有一种方法可以在应用装饰器后"替换"它,但我想可能没有,因为该功能已被更改.
无论如何,您可能会在运行时根据某些条件应用装饰器:
#!/usr/bin/env python class PrintCallInfo: def __init__(self,f): self.f = f def __call__(self,*args,**kwargs): print "-->",self.f.__name__,args,kwargs r = self.f(*args,**kwargs) print "<--",self.f.__name__,"returned: ",r return r # the condition to modify the function... some_condition=True def my_decorator(f): if (some_condition): # modify the function return PrintCallInfo(f) else: # leave it as it is return f @my_decorator def foo(): print "foo" @my_decorator def bar(s): print "hello",s return s @my_decorator def foobar(x=1,y=2): print x,y return x + y foo() bar("world") foobar(y=5)