tags:

views:

52

answers:

4

Is it possible to find out if a function is decorated at runtime? For example could I find all functions in a module that are decorated by "example"?

@example
def test1():
    print "test1"
+2  A: 

In the general case it is not possible because the example decorator might not leave any trace that's detectable at runtime -- for example, it could be

def example(f):
  return f

If you do control the source for example, it's of course easy to make it mark or record the functions it's decorating; if you don't, it may be utterly impossible to do what you want.

Alex Martelli
+2  A: 

I don't think there's a general way since a decorator is a simple function call. Your code is identical to this:

def test1():
    print "test1"

test1 = example(test1)

You could probably detect specific decorators by disassembling and analysing (using the dis module). Or you could simply parse the source file, though that's a bit ugly.

Why do you want to detect them in the first place?

Max Shawabkeh
My script is used to access a RESTful interface. I wanted to introspect my module and find all the methods "marked" with a certain decorator and build my "optparse" options at runtime. Since the decorator enforces some consistency for my arguments, it made sense to check against that as all of the REST endpoints would be decorated by it.
TheDude
If you could edit some sample code from the decorated module and the definition of the decorator, we could probably figure a way to do that.
Max Shawabkeh
I can actually easily achieve what I want if I simply prefixed my "optparse"-able functions with "do_" or something like that. Then I can loop through the functions and create an optparse option for functions that start with "do_". I just felt it would be cleaner to check based on my decorator.
TheDude
If you're the one writing the decorator, you can make it add the function to a module-level variable (then return it) and simply read the variable in the client code.
Max Shawabkeh
A: 

If you can, monkeypatch the decorator at runtime to catch which functions are being passed to it:

decfuncs = []

def decpatch(dec):
  def catchdec(func, *args, **kwargs):
    decfuncs.append(func)
    return dec(func, *args, **kwargs)
  return catchdec

somemodule.somedecorator = decpatch(somemodule.somedecorator)
Ignacio Vazquez-Abrams
+1  A: 

Since you have indicated that you are have control of the wrapper code, here is a simple example

def example(f):
    f.wrapped=True
    return f

@example
def test1():
    print "test1"

def test2():
    print "test2"


print test1.wrapped
print hasattr(test2,'wrapped')
gnibbler