[Tutor] stopping threads?
Michael Sparks
zathras at thwackety.com
Thu Sep 29 21:52:56 CEST 2005
On Thursday 29 September 2005 07:27, Pierre Barbier de Reuille wrote:
> IMO, it is better to explicitely call the base class ... I think it is
> more readable. But I don't know if there is any drawback for any
> solution...
A drawback of NOT using super is that you're potetially setting yourself you
for a fall.
Consider the following code
----(Option 1)----
from hypothetical import SomeBaseClass
class myClass(SomeBaseClass):
def __init__(self, ...):
super(myClass, self).__init__(...)
----(Option 2)----
from hypothetical import SomeBaseClass
class myClass(SomeBaseClass):
def __init__(self, ...):
SomeBaseClass.__init__(self)
In the case of option 1, this will work, and have reliable, predictable
behaviour even if the implementation of SomeBaseClass in the "hypothetical"
library changes from something like:
class SomeBaseClass(ActualBase):
...
To something like:
class SomeBaseClass(ActualBase,mixin1, mixin2):
...
In Option 2, you run the risk of methods higher up the tree being run more
than once. Obviously in your *own* code you can avoid this if you like, but
as soon as you start using and inheriting from classes in other people's
libraries you can't guarantee that you're not running that risk.
I posted an example about this via gmane's email to news gateway last
week, but it doesn't appear to have hit the archive (or the list :) for some
reason, so I've included the reply I gave illustrating what can go wrong if
you don't use super at the end.
Regards,
Michael.
---
Original post regarding super:
Subject: Re: Using superclass __init__ method
paul brian wrote:
> class Base:
> def __init__(self):
> print "hello"
>
> class Child(Base):
> def __init__(self):
> Base.__init__(self)
>
> def foo(self):
> print "foo"
I note this is using "old" style classes. However it's normal to recommend
that people use "new" style classes these days. (I only started using
python after they invented new style classes, hence the quotes around
new/old)
A more canonical example here is this:
class Base(object):
def __init__(self):
print "hello"
class Child(Base):
def __init__(self):
super(Child,self).__init__()
def foo(self):
print "foo"
Whilst this might an esoteric change, it's really to handle the fact that
python has multiple inheritance. Consider:
>>> class ChildOne(Base):
... def __init__(self):
... Base.__init__(self)
... print "Hello from ChildOne"
...
>>> class ChildTwo(Base):
... def __init__(self):
... Base.__init__(self)
... print "Hello from ChildTwo"
...
>>> class GrandChild(ChildOne,ChildTwo):
... def __init__(self):
... ChildOne.__init__(self)
... ChildTwo.__init__(self)
... print "Hello from GrandChild"
...
>>> GrandChild()
Hello from Base
Hello from ChildOne
Hello from Base
Hello from ChildTwo
Hello from GrandChild
<__main__.GrandChild instance at 0x40397f8c>
What you can see here is that the __init__ in Base was executed twice. This
may or may not be a problem with some things, but where people use classes
to "mixin" functionality it can be a real problem.
Consider the alternative using "super" instead:
>>> class Base(object):
... def __init__(self):
... print "Hello from Base"
...
>>> class ChildOne(Base):
... def __init__(self):
... super(ChildOne,self).__init__()
... print "Hello from ChildOne"
...
>>> class ChildTwo(Base):
... def __init__(self):
... super(ChildTwo,self).__init__()
... print "Hello from ChildTwo"
...
>>> class GrandChild(ChildOne,ChildTwo):
... def __init__(self):
... super(GrandChild,self).__init__()
... print "Hello from GrandChild"
...
>>> GrandChild()
Hello from Base
Hello from ChildTwo
Hello from ChildOne
Hello from GrandChild
<__main__.GrandChild object at 0x4039ccac>
Regards,
Michael
More information about the Tutor
mailing list