Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Found a shorter way to do <code>super(B, self).test()</code> -> <code>bubble()</code> from below. </p> <p>(Works with multiple inheritance, doesn't require arguments, correcly behaves with sub-classes)</p> <p>The solution was to use <code>inspect.getmro(type(back_self))</code> (where <code>back_self</code> is a <code>self</code> from callee), then iterating it as <code>cls</code> with <code>method_name in cls.__dict__</code> and verifying that the code reference we have is the one in this class (realized in <code>find_class_by_code_object(self)</code> nested function). </p> <p><code>bubble()</code> can be easily extended with <code>*args, **kwargs</code>.</p> <pre><code>import inspect def bubble(*args, **kwargs): def find_class_by_code_object(back_self, method_name, code): for cls in inspect.getmro(type(back_self)): if method_name in cls.__dict__: method_fun = getattr(cls, method_name) if method_fun.im_func.func_code is code: return cls frame = inspect.currentframe().f_back back_self = frame.f_locals['self'] method_name = frame.f_code.co_name for _ in xrange(5): code = frame.f_code cls = find_class_by_code_object(back_self, method_name, code) if cls: super_ = super(cls, back_self) return getattr(super_, method_name)(*args, **kwargs) try: frame = frame.f_back except: return class A(object): def test(self): print "A.test()" class B(A): def test(self): # instead of "super(B, self).test()" we can do bubble() class C(B): pass c = C() c.test() # works! b = B() b.test() # works! </code></pre> <p>If anyone has a better idea, let's hear it.</p> <p><em>Known bug:</em> (thanks doublep) If <code>C.test = B.test</code> --> "infinite" recursion. Although that seems un-realistic for child class to actually have a method, that has been <code>=</code>'ed from parent's one.</p> <p><s><em>Known bug2:</em> (thanks doublep) Decorated methods won't work (probably unfixable, since decorator returns a closure)...</s> Fixed decorator proble with <code>for _ in xrange(5)</code>: ... <code>frame = frame.f_back</code> - will handle up to 5 decorators, increase if needed. <strong>I love Python!</strong></p> <p>Performance is 5 times worse than <code>super()</code> 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.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload