3

I have a base class with a @classmethod which acts as a decorator for a large number of methods in many descendant classes.

class BaseClass():
    @classmethod
    def some_decorator(cls, method):
        @wraps(method)
        def inner_method(self, *args, **kwargs):
            # do stuff
            return method(self, *args, **kwargs)
        return inner_method


class ChildClass(BaseClass):
    @BaseClass.some_decorator
    def some_child_method(self):
        # do other stuff
        return

When I profile this code and look at it through a tree view, I see thousands of calls to some_decorator from hundreds of different places.

And then I see some_decorator call back out to hundreds of the places it just came from.

It's quite annoying and I have yet to figure out a way around it, neither through changing the code nor profiling a different way. (Using gprof2dot atm: How can you get the call tree with python profilers?)

Thoughts?

Community
  • 1
  • 1
Eric Ihli
  • 1,722
  • 18
  • 30
  • Since a decorator typically makes a closure for each decorated function, couldn't you update (or make a copy of) the code object and change the file and line information to reference a line above the decorated function? – Patrick Maupin May 05 '17 at 20:52

1 Answers1

1

There are ways to build decorators to preserve docs/signatures. The wrapt library provides a lot of functionality to that end.

https://wrapt.readthedocs.io/en/latest/decorators.html#decorating-class-methods

It would end up looking something like this:

class BaseClass():
    @wrapt.decorator
    @classmethod
    def some_decorator(cls, method, instance, *args, *kwargs):
        # do stuff
        return method(instance, *args, **kwargs)
Eric Ihli
  • 1,722
  • 18
  • 30