Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #6255 > unrolled thread

super() in class defs?

Started byJess Austin <jess.austin@gmail.com>
First post2011-05-25 10:54 -0700
Last post2011-05-25 16:45 -0700
Articles 5 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  super() in class defs? Jess Austin <jess.austin@gmail.com> - 2011-05-25 10:54 -0700
    Re: super() in class defs? Ian Kelly <ian.g.kelly@gmail.com> - 2011-05-25 12:31 -0600
      Re: super() in class defs? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-05-25 21:40 +0000
        Re: super() in class defs? Ian Kelly <ian.g.kelly@gmail.com> - 2011-05-25 17:31 -0600
          Re: super() in class defs? Raymond Hettinger <python@rcn.com> - 2011-05-25 16:45 -0700

#6255 — super() in class defs?

FromJess Austin <jess.austin@gmail.com>
Date2011-05-25 10:54 -0700
Subjectsuper() in class defs?
Message-ID<aed43cea-eae7-40d5-a3c9-13b841d3fd7c@c41g2000yqm.googlegroups.com>
I may be attempting something improper here, but maybe I'm just going
about it the wrong way. I'm subclassing
http.server.CGIHTTPRequestHandler, and I'm using a decorator to add
functionality to several overridden methods.

def do_decorate(func):
.   def wrapper(self):
.       if appropriate():
.           return func()
.       complain_about_error()
.   return wrapper

class myHandler(CGIHTTPRequestHandler):
.   @do_decorate
.   def do_GET(self):
.       return super().do_GET()
.   # also override do_HEAD and do_POST

My first thought was that I could just replace that whole method
definition with one line:

class myHandler(CGIHTTPRequestHandler):
.   do_GET = do_decorate(super().do_GET)

That generates the following error:

SystemError: super(): __class__ cell not found

So I guess that when super() is called in the context of a class def
rather than that of a method def, it doesn't have the information it
needs. Now I'll probably just say:

    do_GET = do_decorate(CGIHTTPRequestHandler.do_GET)

but I wonder if there is a "correct" way to do this instead? Thanks!

[toc] | [next] | [standalone]


#6257

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-05-25 12:31 -0600
Message-ID<mailman.2087.1306348325.9059.python-list@python.org>
In reply to#6255
On Wed, May 25, 2011 at 11:54 AM, Jess Austin <jess.austin@gmail.com> wrote:
> So I guess that when super() is called in the context of a class def
> rather than that of a method def, it doesn't have the information it
> needs. Now I'll probably just say:
>
>    do_GET = do_decorate(CGIHTTPRequestHandler.do_GET)
>
> but I wonder if there is a "correct" way to do this instead? Thanks!

I would recommend against using super() in general.

http://fuhm.net/super-harmful/

Cheers,
Ian

[toc] | [prev] | [next] | [standalone]


#6267

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-05-25 21:40 +0000
Message-ID<4ddd774f$0$29996$c3e8da3$5496439d@news.astraweb.com>
In reply to#6257
On Wed, 25 May 2011 12:31:33 -0600, Ian Kelly wrote:

> I would recommend against using super() in general.
> 
> http://fuhm.net/super-harmful/

If you actually read that article, carefully, without being fooled by the 
author's provocative ex-title and misleading rhetoric, you will discover 
that super is not harmful. What is harmful is making unjustified 
assumptions about what super does, and about the code you are calling, 
and hence misusing super.

You have to read all the way to the bottom of the article to see the 
author say in the TODO section:

"Give some examples of why super really is necessary sometimes"

Even before that, you will read why *not* using super often fails badly. 
If James Knight, the author, is correct that super is harmful, it seems 
that you're in trouble because *not using super* is also harmful.

If you search the mailing lists of python-dev@python.org, you will find a 
debate between James and Guido van Russum where James eventually 
acknowledges that he is wrong to call super harmful. There's a reason 
that he has changed the title of the page from "Python's Super Considered 
Harmful" to the damning-with-faint-praise "Python's Super is nifty, but 
you can't use it". 

The new title is also *simply wrong*, because you can use it. James even 
tells you what you need to do to use it correctly.

The truth is that for multiple inheritance, you better be using super or 
your code is probably buggy (unless you manually duplicate what super 
does for you). And for single inheritance, it makes no difference whether 
you use super or not.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#6275

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-05-25 17:31 -0600
Message-ID<mailman.2097.1306366342.9059.python-list@python.org>
In reply to#6267
On Wed, May 25, 2011 at 3:40 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> If you actually read that article, carefully, without being fooled by the
> author's provocative ex-title and misleading rhetoric, you will discover
> that super is not harmful. What is harmful is making unjustified
> assumptions about what super does, and about the code you are calling,
> and hence misusing super.

Yes.  As others have noted, the problem is really multiple
inheritance, not super.  Super can be a useful tool, but unless you
have taken some time to learn its intricacies, I think that it is best
avoided so that it is not misused.

> You have to read all the way to the bottom of the article to see the
> author say in the TODO section:
>
> "Give some examples of why super really is necessary sometimes"
>
> Even before that, you will read why *not* using super often fails badly.
> If James Knight, the author, is correct that super is harmful, it seems
> that you're in trouble because *not using super* is also harmful.

Essentially, super can fail when you use it inconsistently.  Not using
super can fail when you have a diamond inheritance situation, or when
you mix it with super.

In this case, the OP is using super while inheriting from
http.server.CGIHTTPServer, which does not use super, and so is
inconsistent.

> If you search the mailing lists of python-dev@python.org, you will find a
> debate between James and Guido van Russum where James eventually
> acknowledges that he is wrong to call super harmful. There's a reason
> that he has changed the title of the page from "Python's Super Considered
> Harmful" to the damning-with-faint-praise "Python's Super is nifty, but
> you can't use it".

Thanks.  I found this quote from James that pretty much sums up my
position perfectly:

"""
This is where I'm coming from:
In my own code, it is very rare to have diamond inheritance structures.
And if there are, even more rare that both sides need to cooperatively
override a method. Given that, super has no necessary advantage. And it
has disadvantages.
- Backwards compatibility issues
- Going along with that, inadvertent mixing of paradigms (you have to
remember which classes you use super with and which you don't or your
code might have hard-to-find errors).
- Take your choice of: a) inability to add optional arguments to your
methods, or b) having to use *args, **kwargs on every method and call
super with those.
- Having to try/catch AttributeErrors from super if you use interfaces
instead of a base class to define the methods in use.
"""

> The new title is also *simply wrong*, because you can use it. James even
> tells you what you need to do to use it correctly.

Yes, you need to fundamentally alter the structure of your code to
throw away any semblance of run-time argument checking by having every
method that might conceivably be cooperatively inherited take *args,
**kwargs.  You also need to take care to always call super from such
methods, even when it appears to be unnecessary.  And don't forget to
catch the AttributeError if the method is something other than __new__
or __init__ and the current class turns out to be the last one in the
MRO that has it.

In short, if you're using super and don't feel burdened by it, then
you're probably using it incorrectly.

> The truth is that for multiple inheritance, you better be using super or
> your code is probably buggy (unless you manually duplicate what super
> does for you).

No.  For diamond inheritance, you better be using super or your code
is probably buggy.  For typical diamond-less multiple inheritance,
super is both unnecessary and tricky to use correctly.

> And for single inheritance, it makes no difference whether
> you use super or not.

Right.  It's unnecessary, so why saddle yourself with it?

[toc] | [prev] | [next] | [standalone]


#6276

FromRaymond Hettinger <python@rcn.com>
Date2011-05-25 16:45 -0700
Message-ID<fb2bdce2-bee2-425b-b1b1-1c152975f620@l2g2000prg.googlegroups.com>
In reply to#6275
On May 25, 4:31 pm, Ian Kelly <ian.g.ke...@gmail.com> wrote:
> Right.  It's unnecessary, so why saddle yourself with it?

FWIW, I expect to release a blog post tomorrow about the principal use
cases for super() and how to use it effectively.

With just a little bit of know-how, it can be an important tool in
your Python toolkit.

If any of the comp.lang.python readers want to review and comment on
my latest draft, please email me and I'll send it to you directly.

Cheers,


Raymond Hettinger

my email address is listed at http://users.rcn.com/python/download/Descriptor.htm

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web