You can't do that... see things like here:
Python method resolution mystery
Basically. most of special functions are looked up at the class level. Monkey-patching it after initialization won't have any effect.
That said, you should be able to do something like this:
class BaseClass(object):
__call__ = trace(object.__call__)
def __init__(self, ...):
...
Now, it's wrapped at the class level, so it will work.
edit: That's not really an answer. What you want is something like:
class BaseClass(object):
@decorator
__call__ = something
class SubClass(BaseClass):
__call__ = something_else
In this case... it doesn't matter what you put for the BaseClass __call__
method, the SubClass method will override it. It's not about decorators vs. non-decorators, as it's functions (well, really, attributes, since there isn't really much difference in python) that get inherited. Decorators look separate from the function, but they aren't really - in the above, all that the decorator does is change the definition of __call__
from something
to decorator(something)
(which must still return a callable).
Then, in the subclass, you reassign this function to something completely different.
You could use a class decorator, but those things tend to break introspection as you noticed; they turn a class, into a function that returns a class. Similar problem with factory functions.
Maybe look into the profile
module? I know there are some lower-level hooks that it uses to track function calls etc. that you might be able to use as well (though don't know much about them).