When ‘super’ is not a good idea

Scott David Daniels Scott.Daniels at Acm.Org
Wed Oct 7 17:17:25 CEST 2009


Ben Finney wrote:
> Scott David Daniels wrote: ...

>>>     class Initialized(ClassBase):
>>>         @classmethod
>>>         def _init_class(class_):
>>>             class_.a, class_.b = 1, 2
>>>             super(Initialized, class_)._init_class()
>> Mea culpa:  Here super is _not_ a good idea, 
> […]
> Why is ‘super’ not a good idea here?
>>     class Initialized(ClassBase):
>>         @classmethod
>>         def _init_class(class_):
>>             class_.a, class_.b = 1, 2
>>             ClassBase._init_class()
> What makes this implementation better than the one using ‘super’?
> 
Well, it doesn't end with an error message :-)

The reason for the error message is that super is built for instance
methods, not class methods.  You'd need a class method style super
to get to "the next superclass in the __mro__ with an '_init_class'
method."   Personally I don't see the need.
You could of course do it like this:

     class MyOtherType(type):
         def __new__(class_, name, bases, dct):
             result = type.__new__(class_, name, bases, dct)
             result()._init_class()
             return result

     class OtherClassBase(object):
         __metaclass__ = MyOtherType

         def _init_class(self):
             print 'initializing class'

     class Initialized(OtherClassBase):
         def _init_class(self):
             self.__class__.a, self.__class__.b = 1, 2
             super(Initialized, self)._init_class()

This code is a problem because the point of this exercise is to do
initialization _before_ building an instance (think of building tables
used in __init__).

Before you decide that super should simply check if the second arg to
super is a subclass of the first arg, and operate differently in that
case (as my first code naively did), realize there is a problem.  I saw
the problem in trying the code, and simply tacked in the proper parent
call and ran off to work.

Think about the fact that classes are now objects as well; a class
itself has a class (type or in these classes MyType or MyOtherType)
with its own needs for super, and the combination would be a mess.
I'm certain you'd get inadvertent switches across the two subtype
hierarchies, but that belief may just be my fear of the inevitable
testing and debugging issues such an implementation would require.

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list