Is it possible to replace a function/method decorator at runtime? [ python ]

Geo picture Geo · Mar 13, 2009 · Viewed 14.4k times · Source

If I have a function :


@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()

Is it possible to replace a decorator at runtime?

Answer

DNS picture DNS · Mar 13, 2009

As Miya mentioned, you can replace the decorator with another function any point before the interpreter gets to that function declaration. However, once the decorator is applied to the function, I don't think there is a way to dynamically replace the decorator with a different one. So for example:

@aDecorator
def myfunc1():
    pass

# Oops! I didn't want that decorator after all!

myfunc1 = bDecorator(myfunc1)

Won't work, because myfunc1 is no longer the function you originally defined; it has already been wrapped. The best approach here is to manually apply the decorators, oldskool-style, i.e:

def myfunc1():
    pass

myfunc2 = aDecorator(myfunc1)
myfunc3 = bDecorator(myfunc1)

Edit: Or, to be a little clearer,

def _tempFunc():
    pass

myfunc1 = aDecorator(_tempFunc)
myfunc1()
myfunc1 = bDecorator(_tempFunc)
myfunc1()