Trying to convert into a simple nice super(B, self).method()bubble() call.
Did it, see below!
Is it possible to get reference to class B in this example?
class A(object): pass
class B(A):
def test(self):
test2()
class C(B): pass
import inspect
def test2():
frame = inspect.currentframe().f_back
cls = frame.[?something here?]
# cls here should == B (class)
c = C()
c.test()
Basically, C is child of B, B is child of A. Then we create c of type C. Then the call to c.test() actually calls B.test() (via inheritance), which calls to test2().
test2() can get the parent frame frame; code reference to method via frame.f_code;
self via frame.f_locals['self']; but type(frame.f_locals['self']) is C (of course), but not B, where method is defined.
Any way to get B?
Found a shorter way to do
super(B, self).test()->bubble()from below.(Works with multiple inheritance, doesn’t require arguments, correcly behaves with sub-classes)
The solution was to use
inspect.getmro(type(back_self))(whereback_selfis aselffrom callee), then iterating it asclswithmethod_name in cls.__dict__and verifying that the code reference we have is the one in this class (realized infind_class_by_code_object(self)nested function).bubble()can be easily extended with*args, **kwargs.If anyone has a better idea, let’s hear it.
Known bug: (thanks doublep) If
C.test = B.test–> “infinite” recursion. Although that seems un-realistic for child class to actually have a method, that has been=‘ed from parent’s one.Known bug2: (thanks doublep) Decorated methods won’t work (probably unfixable, since decorator returns a closure)…Fixed decorator proble withfor _ in xrange(5): …frame = frame.f_back– will handle up to 5 decorators, increase if needed. I love Python!Performance is 5 times worse than
super()call, but we are talking about 200K calls vs a million calls per second, if this isn’t in your tightest loops – no reason to worry.