Live data from Hacker News

Wield Python's super() like a Jedi

rhettinger.wordpress.com

11–20 of 67 posts

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

#11
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() was introduced in CPython 2.2, but it changed in Python3: http://www.python.org/dev/peps/pep-3135/. The link you posted uses super as "super(cls, instance)", but the main article uses Python 3's super, which can just be called as "super()", and it figures out the class and instance.

So no, super really has changed, and the syntax in the article does not work with very old version of Python.

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

#12
post #9
post #4

Earlier quoted context omitted.

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-...

Python 2.x doesn't have parameterless super() so apparently most of the article's code doesn't work with old versions.

Well, you just change to the Python 2 super call form and it works fine. The substitution hardly requires a master programmer...

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

#13
post #11
post #4

Earlier quoted context omitted.

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() was introduced in CPython 2.2, but it changed in Python3: http://www.python.org/dev/peps/pep-3135/ . The link you posted uses super as "super(cls, instance)", but the main article uses Python 3's super, which can just be called as "super()", and it figures out the class and instance. So no, super really has changed, and the syntax in the article does not work with very old version of Python.

> So no, super really has changed, and the syntax in the article does not work with very old version of Python.

Oh come on, he's saying if you do the incredibly minor syntax adjustment that all of the actual meat of the article still works in Python 2.

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

#14
post #11

Earlier quoted context omitted.

super() was introduced in CPython 2.2, but it changed in Python3: http://www.python.org/dev/peps/pep-3135/ . The link you posted uses super as "super(cls, instance)", but the main article uses Python 3's super, which can just be called as "super()", and it figures out the class and instance. So no, super really has changed, and the syntax in the article does not work with very old version of Python.

> So no, super really has changed, and the syntax in the article does not work with very old version of Python. Oh come on, he's saying if you do the incredibly minor syntax adjustment that all of the actual meat of the article still works in Python 2.

I upvoted the parent, because that syntax distinction is actually fairly giant, always having to name the class and also changing that on renames etc, is a PITA.

It is actually one of the things that annoys me most about Python, I guess this is the first thing that actually tempts me with Python 3. Damn.

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

#15
post #8
post #7

Earlier quoted context omitted.

I don't think it suffers much as the method resolution order (mro) is computed ahead-of-time when creating the class.

so super() is computed ahead of time? That doesn't make sense when you look at his comment: "The calculation depends on both the class where super is called and on the instance’s tree of ancestors." I agree that the class's MRO can be computed ahead of time, but theoretically the instance's order could be different (if a class method changed the definition of __setitem__)

The method resolution order for instances of the same class is always the same for all methods. If the class doesn't implement that method, the interpreter just skips and goes to the next place in the call chain. All super does is call the next method in the chain. So if you have class A(object), class B(A), class C(A), and class D(B, C), the MRO of D's instances will be B C A object. Each time an instance of D calls super, it will call the next method in the chain, not necessarily B's or C's or A's, even if the call to super is in B's method. This is why super() receives the class as a parameter, so it can know from when in the object's mro to start looking up the next method.

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

#16
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.

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

#18
It seems to me that code that uses super() in these creative ways will be very difficult to maintain. You need to understand the subtleties of the MRO just to find out which method is being called. Pitty the poor Python programmer who stumbles into such code without being aware that super() may not call the class's direct base.

I suppose similar criticism can be leveled against many other dynamic techniques, except that this one sacrifices more readability than I'm comfortable with.

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

#19
post #15
post #8

Earlier quoted context omitted.

so super() is computed ahead of time? That doesn't make sense when you look at his comment: "The calculation depends on both the class where super is called and on the instance’s tree of ancestors." I agree that the class's MRO can be computed ahead of time, but theoretically the instance's order could be different (if a class method changed the definition of __setitem__)

The method resolution order for instances of the same class is always the same for all methods. If the class doesn't implement that method, the interpreter just skips and goes to the next place in the call chain. All super does is call the next method in the chain. So if you have class A(object), class B(A), class C(A), and class D(B, C), the MRO of D's instances will be B C A object. Each time an instance of D calls…

"This is why super() receives the class as a parameter" From the docs:

"super(type[, object-or-type])" "super([type[, object-or-type]])" <-- type is optional in python3

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

#20

tl;dr Just looks like super/parent like in other languages. Did i miss something from not reading this?

> Did i miss something from not reading this?

Everything? Mostly the part where, Python being an MI language, a given class A has multiple parents. And these parents are a sequence, not a set, which define a Method Resolution Order, and that method resolution order usually isn't breadth-first either, so Python's super is a graph walker. And because it's explicit, any node in the graph can stop the walking.

This means permuting two parent classes can have significant impact on the semantics of the graph walking, therefore the results of calling super.

Post reply on HN