Search code examples
pythonpython-decorators

How to check if an object is a method definition?


I'd like to write a decorator that does somewhat different things when it gets a function or a method. for example, I'd like to write a cache decorator but I don't want to have self as part of the key if it's a method.

def cached(f):
    def _internal(*args, **kwargs):
        if ismethod(f):
            key = create_key(*args[1:], **kwargs) # ignore self from args
        else: # this is a regular function
            key = create_key(*args, **kwargs)
        return actual_cache_mechanism(key, f, *args, **kwargs)
    return _internal

class A:
    @cached
    def b(self, something):
       ...

@cached
def c(something):
    ...

the problem is that when @cached is called, it cannot distinguish between methods and functions as both are of type function. can that even be done? As I'm thinking of it I feel that actually methods have no idea about the context in which they are being defined in...

Thanks!


Solution

  • This is kind of an ugly hack, but you can use obj.__qualname__ to see if obj was defined in a class, by checking if it has a period

    if "." in obj.__qualname__":
       #obj is a member of an object, so it is a method
    

    I'm not sure if it will work nicely for decorators though, since for this to work the method would need to be defined in the class.