Noah wrote: > Am I the only one that finds the super function to be confusing? > > I have a base class that inherits from object. > In other words new style class: > > class foo (object): > def __init__ (self, arg_A, arg_B): > self.a = arg_A > self.b = arg_B > # Do I need to call __init__ on "object" base class? > > class bar (foo): > def __init__ (self, arg_Z): > self.z = "Z" + arg_Z > foo.__init__(self, 'A', arg_Z) # this is the old-style > class way > def __str__ (self): > return self.a + self.b + self.z > > I don't know how people will use the "bar" class > in terms of inheritance. I don't want to lock anyone > out of multiple inheritance, but I'd like to have to > worry about it as little as possible. From what I've > read using the old style of calling the > base class __init__ can cause conflicts > if the class is later part of a diamond relationship. > > I just want "bar" to initialize the properties that it add > to the base class and to have it tell the base class to > initialize the inherited properties. The old way seemed > clear enough; although, a bit ugly. The super function > seems like it would make this more clear, but > it doesn't (to me). > > Is there a "just do this" answer for 90% of the use cases? > > Yours, > Noah
As far as I can tell, the best way to use super() with an __init__ function is to stick to a rigid function signiture. This means, all __init__'s must either have the same functions, accept parameters in the same order (and handle excess parameters through the *args mechanism), or use keyword arguments (using the **keyargs mechanism). So, use one of the following for all your classes in the hierarchy: def __init__(self, arg1, arg2): # No subclass can add or remove arguments pass def __init__(self, arg1, arg2, *args): # Subclasses can add arguments, but cannot remove or have a different # argument order. The instances must be created with all possible parameters. pass def __init__(self, arg1, arg2, **keyargs): # Subclasses can add or remove arguments, and order doesn't matter. # The instances must be created with all possible keyword parameters. pass Unfortunately, I don't see a way of avoiding this problem with super(). Any such super command resolves in the mro order. Since the mro order invoked at a certain class can change depending on its subclasses, there's no way for the class to predict at design time what super() is going to return. You can predict what will be returned with your class hierarchy, but another programmer can create a multiple-inheritence class that will change the result. Explicitly calling the base class is much easier, but a given class method can be called multiple times in that case. I do wish there was a way to kinda combine the two methods: Explicitly call the super-classes, but do so that each super-method can get called one or no times. Unfortunately, I haven't (yet) found a way to do so that can resolve things right. That's not to say that there isn't a better way. I'm sure that the Python developers had a devil of a time working on this thing. --Jason -- http://mail.python.org/mailman/listinfo/python-list