When profiling a Python app, it’s helpful to have a decorator that wraps functions and reports details about their performance. Assuming you are doing this to report some metric about the function, you’ll want the decorator to work with both bound and unbound functions (IE, regular functions and methods of a class), and if the decorator wraps a method, you’ll probably want to know the name of the class the method belongs to.
There is only one way (update: two ways) I’ve found to do this. They both involve the inspect
module. (There are obvious ways to do it that don’t work with decorators.)
You can’t assume that the first argument in a function always refers to its class because that would break in the case that the function was not a method. However, the strong convention in Python is to name the first argument of methods ‘self’. Relying on this convention, we can easily tell if a function includes such an argument with the inspect
module.
The inspect
module’s getcallargs
function will map the parameter names from a function’s signature to its arguments. Given a function fn
that your decorator wraps, you can call inspect.getcallargs(fn, *args)
at runtime and discover that the first positional argument is the ‘self’ parameter defined in the method’s signature!
Now, the use of ‘self’ is such a strong Pythonic convention that it’s good enough in most cases to use the presence of such a parameter in a function to know that it’s a bound function (again, a class method), and you can then inspect the ‘self’ argument for its class using __class__.__name__
.
Here is an example decorator that will print out the class name of a decorated bound function:
Update: In Python 2.6, which does not include inspect.getcallargs
, you can use inspect.getargspec
to similar effect: