Python's super() considered super!

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri May 27 10:49:08 EDT 2011


On Fri, 27 May 2011 10:33:20 -0400, Mel wrote:

> sturlamolden wrote:
> 
>> I really don't like the Python 2 syntax of super, as it violates the
>> DRY principle: Why do I need to write super(type(self),self) when
>> super() will do? Assuming that 'self' will always be named 'self' in my
>> code, I tend to patch __builtins__.super like this:
>> 
>> import sys
>> def super():
>>     self = sys._getframe().f_back.f_locals['self'] 
>>     return __builtins__.super(type(self),self)
>> 
>> This way the nice Python 3.x syntax can be used in Python 2.x.
> 
> Python causes trouble by letting the users get at the internals, but
> things like this make it worthwhile.

Only if by "worthwhile" you mean "buggy as hell".


>>> import sys
>>>
>>> def super():
...     self = sys._getframe().f_back.f_locals['self']
...     return __builtins__.super(type(self),self)
...
>>> class A(object):
...     def __init__(self):
...         super().__init__()
...
>>> class B(A):
...     def __init__(self):
...         super().__init__()
...
>>> a = A()
>>> b = B()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
  [...]
  File "<stdin>", line 3, in __init__
RuntimeError: maximum recursion depth exceeded


Do not use super(type(self), self), because it does not do what you think 
it does:

b = B() calls B.__init__(self)
... which calls super(type(self), self) = super(B, self)
... which calls A.__init__(self)
... which calls super(type(self), self) = super(B, self) *not* A
... which loops forever

type(self) does not return B inside B methods and A inside A methods, it 
returns the class of the instance.


-- 
Steven



More information about the Python-list mailing list