user189728
user189728

Reputation: 288

Find owner class of a method in Python

I'm writing decorators, and part of what I need to do is discern whether a function is a function or a method. Is there a way I can find what class a given method is a part of?

e.g. If I was to run this code, what could I write in getOwner to make exampleFunc print something like <class '__main__'.Example>?

class Example:
    def method(self):
        print("I'm a method")

def exampleFunc(func):
    owner = getOwner(func)
    print(owner)

test = Example()
exampleFunc(test.method)

Upvotes: 6

Views: 2358

Answers (2)

Hans Musgrave
Hans Musgrave

Reputation: 7111

If all you need to do is figure out of the thing behaving like a function is a method or a function, that is one purpose of the types module.

import types

def is_method(f):
    return type(f) == types.MethodType

In the event that the function-like object is a method, you can find its parent class as follows.

Update Patched for Python3 compatibility.

def method_parent(f):
    return f.__self__

Upvotes: 6

cs95
cs95

Reputation: 402483

If you have a reference to the classes defined in your scope, you'd need to check for each one:

def exampleFunc(f):
    class_list = [...]
    return any(f in vars(c).values() for c in class_List)

This will return True if function f is an instance method. However, if you wish to return the actual class name:

def exampleFunc(f):
    class_list = [...]
    for c in class_list:
        if f in vars(c).values():
            return c.__name__

    return 'global function' if 'lambda' not in f.__name__ else 'lambda'

Note that this does not work for __dunder__ methods, and methods that your class inherits. For example,

class A:
    def f1(self): pass

class B(A):
    def f2(self): pass

print(vars(B)) 
mappingproxy({'__doc__': None,
              '__module__': '__main__',
              'f2': <function __main__.B.f2>})

Note that f1 is not a part of B's mappingproxy.

Upvotes: 1

Related Questions