consequences of not calling object.__init__?

S

Steven Bethard

So when I'm writing a class and I define an __init__ method, I sometimes
haven't called object.__init__, e.g.:

class C(object):
def __init__(self, x):
self.x = x

instead of

class C(object):
def __init__(self, x):
super(C, self).__init__()
self.x = x

Looking at:

http://www.python.org/2.2.3/descrintro.html#__new__
"The built-in type 'object' has a dummy __new__ and a dummy __init__"

seems to suggest that the super call here is unnecessary. It's also not
made in the Super class example from that document:

http://www.python.org/2.2.3/descrintro.html#superexample

I'm trying to get in the habit of calling super in all __init__ methods,
but it seems like it's unnecessary when the only superclass is object.
Assuming that the base class of C doesn't get changed from object, are
there consequences of not making this call?


Steve
 
S

Steve Holden

Steven said:
So when I'm writing a class and I define an __init__ method, I sometimes
haven't called object.__init__, e.g.:

class C(object):
def __init__(self, x):
self.x = x

instead of

class C(object):
def __init__(self, x):
super(C, self).__init__()
self.x = x

Looking at:

http://www.python.org/2.2.3/descrintro.html#__new__
"The built-in type 'object' has a dummy __new__ and a dummy __init__"

seems to suggest that the super call here is unnecessary. It's also not
made in the Super class example from that document:

http://www.python.org/2.2.3/descrintro.html#superexample

I'm trying to get in the habit of calling super in all __init__ methods,
but it seems like it's unnecessary when the only superclass is object.
Assuming that the base class of C doesn't get changed from object, are
there consequences of not making this call?
The principal one that I can see is that you are relying on this
implementation feature to maintain forward compatibility, since I'm not
aware of any pronouncement that says "object will *always* have a dummy
__init__".

There's also the possibility that you might want to use a different base
class later (for example, setting

object = mySuperDebugObject

for debugging purposes). If that object has an __init__() method you'll
have to put the calls in then anyway.

Perhaps a relevant question is how long it takes to call the __init__
method using super.

sholden@dellboy ~/Projects/PyCON2005
$ python /usr/lib/python2.4/timeit.py -s "
class C(object):
def __init__(self, x):
self.x = x" "C(1)"
100000 loops, best of 3: 2.69 usec per loop

sholden@dellboy ~/Projects/PyCON2005
$ python /usr/lib/python2.4/timeit.py -s "
class C(object):
def __init__(self, x):
super(C, self).__init__()
self.x = x" "C(1)"
100000 loops, best of 3: 5.58 usec per loop

So, even on my cronky old 1.3 GHz laptop [1] you only lose 3
microseconds per object creation. You'll have to decide how significant
that is.

regards
Steve

[1]: Freaky - I had just typed this when the doorbell went, and it was
the UPS driver delivering the new laptop!
 
J

John Lenton

in the code that follows, instances of E haven't been through D's
rigorous initiation process

.. class C(object):
.. def __init__(self):
.. print "C"
..
.. class D(object):
.. def __init__(self):
.. print "D"
.. super(D, self).__init__()
..
.. class E(C, D):
.. def __init__(self):
.. print "E"
.. super(E, self).__init__()
 
S

Steven Bethard

John said:
in the code that follows, instances of E haven't been through D's
rigorous initiation process

. class C(object):
. def __init__(self):
. print "C"
.
. class D(object):
. def __init__(self):
. print "D"
. super(D, self).__init__()
.
. class E(C, D):
. def __init__(self):
. print "E"
. super(E, self).__init__()

Ahh, there's the example I was looking for. =)

Thanks!

Steve
 
S

Shalabh Chaturvedi

Steven said:
So when I'm writing a class and I define an __init__ method, I sometimes
haven't called object.__init__, e.g.:

class C(object):
def __init__(self, x):
self.x = x

instead of

class C(object):
def __init__(self, x):
super(C, self).__init__()
self.x = x

Looking at:

http://www.python.org/2.2.3/descrintro.html#__new__
"The built-in type 'object' has a dummy __new__ and a dummy __init__"

seems to suggest that the super call here is unnecessary. It's also not
made in the Super class example from that document:

http://www.python.org/2.2.3/descrintro.html#superexample

I'm trying to get in the habit of calling super in all __init__ methods,
but it seems like it's unnecessary when the only superclass is object.
Assuming that the base class of C doesn't get changed from object, are
there consequences of not making this call?

Yes!

Consider what happens if you multi-subclass from the above C class and
another class D.

class E(C, D):
def __init__(self, x):
super(E, self).__init__(x)
# some initialization for E

Now E.__mro__ is (E,C,D,object). So:

1. E's __init__ should call C's __init__ (this happens due to super call
in E.__init__)

2. C's __init__ should call D's __init__ (*this is why you need the
super call in C.__init__*)

Without it, D.__init__ will not be called. Note that D.__init__ should
not take any parameters in this case. Parameter similarity may be an
issue in call-next-method technique.

However, if you know you will not mutli-subclass from C, you may leave
out the super call.

HTH,
Shalabh
 
P

Peter Hansen

Steve said:
The principal one that I can see is that you are relying on this
implementation feature to maintain forward compatibility, since I'm not
aware of any pronouncement that says "object will *always* have a dummy
__init__".

Maybe there's no such pronouncement, but unless there is a
clear statement somewhere (and I believe I've missed it, if
there is) that reads "one should *always* call __init__ on the
superclass even if one is just subclassing object and not
dealing with multiple inheritance situations", then I would
submit that the majority of Python code written using new-style
classes would be broken should what you suggest above ever
actually happen... starting with much of the code in the
standard library (based on a quick glance at those modules
whose contents match the re pattern "class .*(object):" .

-Peter
 
J

Jorge Luiz Godoy Filho

Peter said:
Maybe there's no such pronouncement, but unless there is a
clear statement somewhere (and I believe I've missed it, if
there is) that reads "one should *always* call __init__ on the
superclass even if one is just subclassing object and not
dealing with multiple inheritance situations", then I would
submit that the majority of Python code written using new-style
classes would be broken should what you suggest above ever
actually happen... starting with much of the code in the
standard library (based on a quick glance at those modules
whose contents match the re pattern "class .*(object):" .

Things are kind weird at this point, since there are too many things to
think about and to make a decision on what should be done and what is
recommended to be done...

Quoting from http://www.python.org/peps/pep-0008.html:

"""
(...)
Designing for inheritance
(...)
Also decide whether your attributes should be private or not.
The difference between private and non-public is that the former
will never be useful for a derived class, while the latter might
be. Yes, you should design your classes with inheritence in
mind!
(...)
"""

So, I don't really know which is correct: to always call the constructor of
the parent class or just do that when it is needed by design...

I think that based on the above quotation from PEP-0008 code in the standard
library should be calling the parent class constructor. But then, I'm one
of the people who never do that :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top