I'm working on a decorator that runs a function on the first argument of the decorated method that is not self. To accomplish this, I am currently using two decorators with basically the same code. The only difference is that one has a function that contains self before the first argument.
import functools
def wrap(function):
@functools.wraps(function)
def wrapper(first_argument, *args, **kwargs):
someFuntion(first_argument)
return function(first_argument, *args, **kwargs)
return wrapper
def wrapClass(function):
@functools.wraps(function)
def wrapper(self, first_argument, *args, **kwargs):
someFuntion(first_argument)
return function(self, first_argument, *args, **kwargs)
return wrapper
I would like to combine the two decorators into a single one in a format like this:
import functools
def wrap(function):
if isPartOfClass(function):
@functools.wraps(function)
def wrapper(self, first_argument, *args, **kwargs):
someFuntion(first_argument)
return function(self, first_argument, *args, **kwargs)
else:
@functools.wraps(function)
def wrapper(first_argument, *args, **kwargs):
someFuntion(first_argument)
return function(first_argument, *args, **kwargs)
return wrapper
In Python 2 I used to be able to simply detect if the function was an unbound method. However, I know that that concept was removed in Python 3.
I've already come up with several detection methods that won't work.
- I could first check if the first argument is called
self, but that is not the required name. - I could try to detect whether the function has 1 (regular) or 2 (class) arguments, but the regular function might contain more than 1 argument. Regardless of the number of arguments, I only care about the first argument that is not self.
- I could attempt to detect the first argument based on type, but there is no guarantee of exactly what type it will be.
Is there any practical way for me to do this detection, or am I going to be stuck with the two decorators?
classblock, the method isn't "part of" a class. The object representing the class isn't created until after all the objects representing the methods (which are at this point still just ordinary functions) are.