Live data from Hacker News

Wield Python's super() like a Jedi

rhettinger.wordpress.com

51–60 of 67 posts

Re: Wield Python's super() like a Jedi

#52
post #24

Personally I'm not in favor of enforcing such strict conventions, especially in a dynamic language like Python. Also isn't this pattern he repeats throughout: class Shape: def __init__(self, **kwds): self.shapename = kwds.pop('shapename') super().__init__(**kwds) Better written like this? class Shape: def __init__(self, shapename=None, **kwds): self.shapename = shapename super().__init__(**kwds) It seems like there a…

Haha, the author is one of the main contributors to python, not some high-schooler.

  kwds.pop('shapename', None) 
Will get you what you're looking for.

Re: Wield Python's super() like a Jedi

#53
post #47

The " kwds" technique is actually something I came up with independently to solve a different problem when I was using PyGame: ridiculously long argument lists when constructing sprites. In this case it significantly increased the flexibility and brevity of the code, although perhaps with a more complicated inheritance tree it wouldn't be worth it. Nice to see this pattern being acknowledged somewhere else; I thought…

It's a great technique. I'm sure your PyGame code benefitted in a big way :-)

Re: Wield Python's super() like a Jedi

#54

A true Jedi favors composition.

Good advice and well spoken :-) That being said, composing a number of object classes also involves some measure of cooperation, caller/callee ordination, and some plan for calling the methods in the correct order.

IOW, if the decomposition of the classes is the same, then the solutions using composition or using multiple inheritance will have much in common.

Things should be as simple as possible, but no simpler :-)

Re: Wield Python's super() like a Jedi

#55
post #50

Earlier quoted context omitted.

Unfortunately on PyPy super is less efficient than refering directly to the parent classes method, however it's fixable (and will be fixed).

Do you have some sort of timing measure?

No, I haven't timed it myself, I just know how it's implemented and what code we're generating internally.

Edit: To be clear I would not advocate not using super() on account of this, as I said it'll eventually be fixed.

Re: Wield Python's super() like a Jedi

#56
post #3

Have to deal with enough languages as it is. Don't want to further add to my brain mess by learning Python 3 syntax just yet.

Python 3 was introduced two and a half years ago. Its major syntactic changes, while frustrating if you're set in your ways, are hardly insurmountable.

I think it's fine if you're doing python all day long, but I'm using Python, Java, PHP, Obj-C and Javascript each at least once a month on a variety of paid and personal projects. Like I said, I have enough trouble keeping those syntaxes straight.

Re: Wield Python's super() like a Jedi

#57
post #4
post #3

Have to deal with enough languages as it is. Don't want to further add to my brain mess by learning Python 3 syntax just yet.

super() was introduced in Python2.2 many years ago. Everything in the article works with very old versions of Python. Here's a link to the Python 2 version of the examples: http://code.activestate.com/recipes/577721-how-to-use-super-...

super(myclass, self) was. Like I posted below, sometimes I have real trouble keeping the 5 or so languages I use straight. The other day I actually forgot what 'None' is in python because I hadn't used it in a few days, and None is different than in the others.

Re: Wield Python's super() like a Jedi

#58

It seems to me that the example of combining built-in dictionary classes is naively optimistic. For starters, OrderedDict, as it happens, does not use super! It calls the dict super-class methods directly. Since dict happens to be the next class in the MRO, this doesn't really matter for the purpose of this example, but I can envision a scenario where some plucky programmer inherits from both OrderedCounter and some…

why would you have to subclass DefaultOrderedCounter again in order to add in the missing method?

Though I agree there's something annoying going on there with the multiple inheritence.

Re: Wield Python's super() like a Jedi

#59
post #43

I didn't see it linked in the article nor mentioned here already but several of the problems with `super` have been discussed in "Python's Super is nifty, but you can't use it"[1] for quite some time. [1]: http://fuhm.net/super-harmful/

That article is about Python 2's super, which is a different beast. Lessons were learnt in the design of Python 3's version.

Re: Wield Python's super() like a Jedi

#60
post #51

A true Jedi favors composition.

One of the reasons I'm starting to love Go more than Python. In Go something like super() is superfluous.

The only reason why you don't need super in Go is because you cannot embed multiple interfaces except if their sets of methods are disjoint. This eliminates super's job of allowing programmers to differentiate between base classes with conflicting method implementations.

Without this, Go requires you to design your class hierarchy in a way that is cleaner, but the super concept is still not superfluous -- because you do sometimes need to reference an ancestor's implementation in Go.

You embed an interface and then explicitly reference the embedded interface by name. The Go interface

  type ReaderWriter interface {
    Reader
    Writer
  }
is exactly like this Python

  class ReaderWriter(Reader, Writer):
    pass
To get at a particular superclass implementation, you pass the class to super, like so:

  def read_and_write(self):
    super(Reader).read()
    super(Writer).write()
which in Go is:

  func (rw *ReaderWriter) ReadAndWrite() {
    rw.Reader.read()
    rw.Writer.write()
  }

So it's not superfluous -- there's an equivalent syntax to super which involves referencing embedded interfaces.
Post reply on HN