Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to gain access to the class of a method when all you have is a callable

I have code that is like:

class Foo:
    def foo(self):
        pass


class Bar:
    def foo(self):
        pass

f = random.choice((Foo().foo, Bar().foo))

How do I access Bar or Foo from f?

f.__dict__ is of little to no help, but as repr(f) gives <bound method Bar.foo of <__main__.Bar object at 0x10c6eec18>>' it must be possible, but how?

like image 340
Kimvais Avatar asked Nov 18 '15 14:11

Kimvais


1 Answers

Each bound method has the __self__ attribute which is the

instance to which this method is bound, or None

(copied from here)

More about bound methods (from Data Model):

If you access a method (a function defined in a class namespace) through an instance, you get a special object: a bound method (also called instance method) object. ... Bound methods have two special read-only attributes: m.__self__ is the object on which the method operates...

So f.__self__ will get you the class instance:

print(f.__self__) # <__main__.Foo object at 0x7f766efeee48>

And type(f.__self__) or f.__self__.__class__ will get you the type object:

print(type(f.__self__)) # <class '__main__.Foo'>

You'd only use __class__ for old-style classes.

like image 138
vaultah Avatar answered Nov 15 '22 18:11

vaultah