Search code examples
pythonintrospection

Python: Can you find the parent class from a variable containing a function?


Given the following program:

from functools import update_wrapper                                                                                      

class MyClass:                                                                                                            
    @classmethod                                                                                                          
    def my_function(cls):                                                                                                 
        def another_function():                                                                                           
            print('hello')                                                                                                
        return update_wrapper(another_function, cls)                                                                      

def do_something(the_func):                                                                                              
    print(the_func)                                                                                                             
    # <function MyClass at 0x7f5cb69fd848>                                                                               
    print(the_func.__class__)                                                                                                   
    # <type 'function'>                                                                                                  
    print(the_func())                                                                                                     

x = MyClass()                                                                                                            
y = x.my_function()                                                                                                      

do_something(y)                                                                                                          

In my do_something function, how can I identify that the 'the_func' variable came from the 'MyClass' class? Specifically, how can I get an un-instantiated reference to MyClass?

print(dir(the_func))

...returns nothing obvious.


Solution

  • Look at the __wrapped__ dunder:

    >>> y.__wrapped__
    __main__.MyClass
    

    It's functools.update_wrapper that adds this attribute.

    I also want to point out that your usage of update_wrapper is somewhat strange. It would be more usual to use my_function and another_function here rather than another_function and cls. Then you would access the class object through __wrapped__ and __self__.