472,954 Members | 1,589 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,954 software developers and data experts.

super and __init__

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

Sep 8 '06 #1
4 3201
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

Sep 8 '06 #2

Jason wrote:
Noah wrote:
Am I the only one that finds the super function to be confusing?

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.
If I know that multiple calls to my base class __init__ is harmless
and multiple calls to my derrived class __init__ is harmless then
is it best to just go ahead and use the old style of explicitly calling
the __init__? I'm just worried about using the old style base __init__
call
with new style objects.

Since inheritance is so fundemental to an object oriented language
it's bad that Python makes it so easy to get the constructor wrong.

Yours,
Noah

Sep 8 '06 #3
"Jason" <te***********@gmail.comwrote:
As far as I can tell, the best way to use super() with an __init__
function is to stick to a rigid function signiture.
....
Unfortunately, I don't see a way of avoiding this problem with super().
An easy way to avoid changing the method signature is to use a multi-stage
construction. So if your class hierarchy uses:

def __init__(self, foo, bar):
super(ThisClass, self).__init__(foo, bar)
... whatever ...

and you are adding another class to the hierarchy, but that needs a 'baz'
as well, don't change the signature for __init__, add another method:

def set_baz(self, baz): ...

Then at the point you construct the objects you can call:

x = DerivedClass(foo, bar)
x.set_baz(baz)

If set_baz isn't called then you either use a default value or throw an
error when something depends on it having been set.

Sep 9 '06 #4
Noah wrote:
Am I the only one that finds the super function to be confusing?
No, see for instance http://fuhm.net/super-harmful/

Michele Simionato

Sep 11 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Nicolas Lehuen | last post by:
Hi, I hope this is not a FAQ, but I have trouble understanding the behaviour of the super() built-in function. I've read the excellent book 'Python in a Nutshell' which explains this built-in...
0
by: Delaney, Timothy C (Timothy) | last post by:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195 This is a new version of super that automatically determines which method needs to be called based on the existing stack frames....
5
by: Christopher J. Bottaro | last post by:
Why don't this code work? import PRI class Poscdnld_PYIO(PRI.BasicBatch): def __init__(self, *argv): super(Poscdnld_PYIO, self).__init__(*argv) x = Poscdnld_PYIO()
2
by: Michael P. Soulier | last post by:
Ok, this works in Python on Windows, but here on Linux, with Python 2.4.1, I'm getting an error. The docs say: A typical use for calling a cooperative superclass method is: class C(B):...
20
by: km | last post by:
Hi all, In the following code why am i not able to access class A's object attribute - 'a' ? I wishto extent class D with all the attributes of its base classes. how do i do that ? thanks in...
1
by: Alex Greif | last post by:
Hi, Before 2.2 I could initialize multiple super classes like this: class B(A,AA): def __init__(self, args): A.__init__(self,args) AA.__init__(self,args) Tutorials say that since python 2.2...
7
by: Kent Johnson | last post by:
Are there any best practice guidelines for when to use super(Class, self).__init__() vs Base.__init__(self) to call a base class __init__()? The super() method only works correctly in multiple...
5
by: Nagarajan | last post by:
Hi group, I am confused with "super" usage..It seems to be complicated and less obvious. Here is what I need to achieve.. class A : def __init__( self ): self.x = 0 class B ( A ):
6
by: exhuma.twn | last post by:
This is something that keeps confusing me. If you read examples of code on the web, you keep on seeing these three calls (super, apply and __init__) to reference the super-class. This looks to me...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.