Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

toggling decorators

What's the best way to toggle decorators on and off, without actually going to each decoration and commenting it out? Say you have a benchmarking decorator:

# deco.py
def benchmark(func):
  def decorator():
    # fancy benchmarking 
  return decorator

and in your module something like:

# mymodule.py
from deco import benchmark

class foo(object):
  @benchmark
  def f():
    # code

  @benchmark
  def g():
    # more code

That's fine, but sometimes you don't care about the benchmarks and don't want the overhead. I have been doing the following. Add another decorator:

# anothermodule.py
def noop(func):
  # do nothing, just return the original function
  return func

And then comment out the import line and add another:

# mymodule.py
#from deco import benchmark 
from anothermodule import noop as benchmark

Now benchmarks are toggled on a per-file basis, having only to change the import statement in the module in question. Individual decorators can be controlled independently.

Is there a better way to do this? It would be nice to not have to edit the source file at all, and to specify which decorators to use in which files elsewhere.

like image 424
engineerC Avatar asked Jan 31 '13 22:01

engineerC


1 Answers

You could add the conditional to the decorator itself:

def use_benchmark(modname):
    return modname == "mymodule"

def benchmark(func):
    if not use_benchmark(func.__module__):
        return func
    def decorator():
        # fancy benchmarking 
    return decorator

If you apply this decorator in mymodule.py, it will be enabled; if you apply it in othermodule.py, it will not be enabled.

like image 152
nneonneo Avatar answered Sep 20 '22 14:09

nneonneo