Quantcast

Super object usage explanation

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Super object usage explanation

Ray Pasco-4
Perhaps this should have been posted on a Python board, but I only care about how this applies to wxPython classes.

General explanations and definitions of the Python super method have fallen far short for me, so I was wondering why it would wanted to be used in a class definition. That is, what are its advantages and hazards ? (I've seen lots of posts about its hazards, but I can't decipher what they mean because I can't figure out what super does in the first place!)

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

mw-10
Did you see this thread from a couple weeks ago?
http://groups.google.com/group/wxpython-users/browse_thread/thread/f9860b459f4dbc5b?hl=en#


On Thu, Mar 3, 2011 at 11:16 AM, Ray Pasco <[hidden email]> wrote:
Perhaps this should have been posted on a Python board, but I only care about how this applies to wxPython classes.

General explanations and definitions of the Python super method have fallen far short for me, so I was wondering why it would wanted to be used in a class definition. That is, what are its advantages and hazards ? (I've seen lots of posts about its hazards, but I can't decipher what they mean because I can't figure out what super does in the first place!)

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Ray Pasco-4
On Mar 3, 2:38 pm, mw <[hidden email]> wrote:
> Did you see this thread from a couple weeks ago?http://groups.google.com/group/wxpython-users/browse_thread/thread/f9...

Yes, that's why I'm asking in the first place! That thread assumes the reader already has a basic understanding of super(). I do not. What does super() do ?

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Tim Roberts
Ray Pasco wrote:
On Mar 3, 2:38 pm, mw <[hidden email]> wrote:
> Did you see this thread from a couple weeks ago?http://groups.google.com/group/wxpython-users/browse_thread/thread/f9...

Yes, that's why I'm asking in the first place! That thread assumes the reader already has a basic understanding of super(). I do not. What does super() do ?

It is a "shortcut" to allow you to access the base class of a derived class, without having to know or type the base class name.  For example:

    class This_is_a_very_long_class_name(object):
        def __init__(self):
            pass

    class Derived(This_is_a_very_long_class_name):
        def __init__(self):
            super(Derived,self).__init__()   #1
            This_is_a_very_long_class_name.__init__(self)    #2


Those last two lines are two ways of spelling the same thing.  Besides just the spelling, this also allows you to change the base class without having to go through all of your code and replace the base class name.  C++ programmers often do this with a typedef in their derived classes.

There is another more obscure use for super as well, but you're unlikely to come across it for a while yet.
-- 
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Boštjan Mejak
Which obscure use is that? Please tell us. This was very informal for other newbies as well. So do tell more.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Ray Pasco-4
In reply to this post by Tim Roberts
On Mar 4, 8:12 pm, Tim Roberts <[hidden email]> wrote:

> It is a "shortcut" to allow you to access the base class of a derived
> class, without having to know or type the base class name.  For example:
>
>     class This_is_a_very_long_class_name(object):
>         def __init__(self):
>             pass
>
>     class Derived(This_is_a_very_long_class_name):
>         def __init__(self):
>             super(Derived,self).__init__()   #1
>             This_is_a_very_long_class_name.__init__(self)    #2
>
> Those last two lines are two ways of spelling the same thing.  Besides
> just the spelling, this also allows you to change the base class without
> having to go through all of your code and replace the base class name.
> C++ programmers often do this with a typedef in their derived classes.
> --
> Tim Roberts, [hidden email]
> Providenza & Boekelheide, Inc.

Thanks! So, it's a way of deriving  my own class by way of another
derived class ?

Do I understand correctly that in your example both the original class
and the newly derived class need to be initialized ?

What are the advantages to calling super() and doing this ? With class
inheritance I already have control over initialization of the base
class.  I must be missing something else.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Robin Dunn
In reply to this post by Boštjan Mejak
On 3/5/11 2:23 AM, Boštjan Mejak wrote:
> Which obscure use is that? Please tell us. This was very informal for
> other newbies as well. So do tell more.

http://docs.python.org/library/functions.html#super

I expect that Tim was thinking of the ability to delegate to a sibling
class in multiple inheritance situations.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Robin Dunn
In reply to this post by Ray Pasco-4
On 3/5/11 8:40 AM, Ray Pasco wrote:
> What are the advantages to calling super() and doing this ? With class
> inheritance I already have control over initialization of the base
> class.  I must be missing something else.
>

It's so you can get to the parent (or sibling) class without knowing the
name of that class.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Robin Dunn
On 3/5/11 8:45 AM, Robin Dunn wrote:
> On 3/5/11 8:40 AM, Ray Pasco wrote:
>> What are the advantages to calling super() and doing this ? With class
>> inheritance I already have control over initialization of the base
>> class. I must be missing something else.
>>
>
> It's so you can get to the parent (or sibling) class without knowing the
> name of that class.
>

Try running this:


class A(object):
     def foo(self):
         print 'A'

class B(A):
     def foo(self):
         print 'B'
         super(B, self).foo()

class C(A):
     def foo(self):
         print 'C'
         super(C, self).foo()

class D(B,C):
     def foo(self):
         print 'D'
         super(D, self).foo()

d = D()
d.foo()


Notice that A is printed only once even though it is derived from twice
in the class hierarchy, and also that B does not have to know that it
should delegate to C before A because C is the next class in the MRO of D.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Ray Pasco-4
Try running this:
...

Notice that A is printed only once even though it is derived from twice in the class hierarchy, and also that B does not have to know that it should delegate to C before A because C is the next class in the MRO of D.
--
Robin Dunn
Software Craftsman
http://wxPython.org

Your code explains most of what I wanted to know. The attached code is just an expansion of the original code. When run, it outputs:
 
a.foo()
A_BaseClass.foo()

b.foo()
B_BaseClass.foo()

c.foo()
C_DerivedClass.foo()
A_BaseClass.foo()

d.foo()
D_DerivedClass.foo()
B_BaseClass.foo()

e.foo()
E_DoubleyDerivedClass.foo()
A_BaseClass.foo()

f.foo()
E_DoubleyDerivedClass.foo()
A_BaseClass.foo()

When e.foo() and f.foo() is called, why isn't B_BaseClass().foo called ?

Meaning, how do I initialize the rest of the base classes after the first one listed in the derivation class list ?

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en

Super_Demo.py (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Tim Roberts
In reply to this post by Boštjan Mejak
Boštjan Mejak wrote:
Which obscure use is that? Please tell us. This was very informal for other newbies as well. So do tell more.

Python allows multiple inheritance.  Although not terribly common, it is possible to construct complicated inheritance trees, including a "diamond" pattern, in which several of your base classes derive from some common ancestor.  If you just use the normal method of calling a base class, like the following, you end up calling the D constructor twice, once from B, once from C:
class D(object):
    def __init__(self):
        print "In D.__init__"
        object.__init__(self)

class B(D):
    def __init__(self):
        print "In B.__init__"
        D.__init__(self)

class C(D):
    def __init__(self):
        print "In C.__init__"
        D.__init__(self)

class A(B,C):
    def __init__(self):
        print "In A.__init__"
        B.__init__(self)
        C.__init__(self)

A()
But if you religiously use "super" instead, it handles this case correctly, and the "D" constructor will only be called once:
class D(object):
    def __init__(self):
        print "In D.__init__"
        super(D,self).__init__()

class B(D):
    def __init__(self):
        print "In B.__init__"
        super(B,self).__init__()

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

class A(B,C):
    def __init__(self):
        print "In A.__init__"
        super(A,self).__init__()

A()
-- 
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Tim Roberts
In reply to this post by Ray Pasco-4
Ray Pasco wrote:

> On Mar 4, 8:12 pm, Tim Roberts <[hidden email]> wrote:
>> It is a "shortcut" to allow you to access the base class of a derived
>> class, without having to know or type the base class name.  For example:
>>
>>     class This_is_a_very_long_class_name(object):
>>         def __init__(self):
>>             pass
>>
>>     class Derived(This_is_a_very_long_class_name):
>>         def __init__(self):
>>             super(Derived,self).__init__()   #1
>>             This_is_a_very_long_class_name.__init__(self)    #2
>>
>> Those last two lines are two ways of spelling the same thing.  Besides
>> just the spelling, this also allows you to change the base class without
>> having to go through all of your code and replace the base class name.
>> C++ programmers often do this with a typedef in their derived classes.
>> --
>> Tim Roberts, [hidden email]
>> Providenza & Boekelheide, Inc.
> Thanks! So, it's a way of deriving  my own class by way of another
> derived class ?

Well, you have always been able to derive classes from other classes.
That's a big feature of Python.

> Do I understand correctly that in your example both the original class
> and the newly derived class need to be initialized ?

Yes, although __init__ is just one example.  It's easy to use as an
example, because it's easy to demo, but you can use any function there.
Technically, the "super" function returns a proxy object of the type
that would have been created had your class not been there.  There is a
clear rule (in Python) for determining the next base class, and "super"
returns an object of the next class in that list.


> What are the advantages to calling super() and doing this ? With class
> inheritance I already have control over initialization of the base
> class.  I must be missing something else.

Because sometimes you don't know -- and don't need to know -- the
ancestry of the classes you derive from.  If you look at my other
example, I have an class A that derives from B and C.  I can certainly
call B's and C's constructor explicitly, but if  both of those classes
derive from a common class D (perhaps through several intermediate
classes), then I have a problem.  The explicit calls will end up calling
D's constructor twice.  The super() function solves that problem.

You can still have control over the ordering.  The ordering rules in
Python are clearly stated (although not commonly known).  You control
the ordering of the base class calls by tweaking the ordering in your class:

    class A( B, C ):

Now, honestly, I don't know whether B or C is first in the list, because
it hasn't been important for me, but the rule is explicit, and it's in
the Python documentation.

--
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Robin Dunn
In reply to this post by Ray Pasco-4
On 3/6/11 10:33 AM, Ray Pasco wrote:

>     Try running this:
>     ...
>
>     Notice that A is printed only once even though it is derived from
>     twice in the class hierarchy, and also that B does not have to know
>     that it should delegate to C before A because C is the next class in
>     the MRO of D.
>     --
>     Robin Dunn
>     Software Craftsman
>     http://wxPython.org
>
>
> Your code explains most of what I wanted to know. The attached code is
> just an expansion of the original code. When run, it outputs:
>

> When e.foo() and f.foo() is called, why isn't B_BaseClass().foo called ?

Because your A and B classes do not participate in the MRO.  In other
words, they break the chain because they do not use super() themselves.

>
> Meaning, how do I initialize the rest of the base classes after the
> first one listed in the derivation class list ?

class A_BaseClass( object ) :
     def foo( self ) :
         print 'A_BaseClass.foo()'
         if hasattr(super( A_BaseClass, self ), 'foo'):
             super( A_BaseClass, self ).foo()


--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Super object usage explanation

Ray Pasco-4
> > Meaning, how do I initialize the rest of the base classes after the
> > first one listed in the derivation class list ?

> class A_BaseClass( object ) :
>      def foo( self ) :
>          print 'A_BaseClass.foo()'
>          if hasattr(super( A_BaseClass, self ), 'foo'):
>              super( A_BaseClass, self ).foo()
>
> --
> Robin Dunn
> Software Craftsmanhttp://wxPython.org

Thanks, Tim and Robin.  I'm going to have to take some so I can wrap
my brain around all this.

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Loading...