
I have read the python3.5 docs for super() and https://rhettinger.wordpress.com/2011/05/26/super-considered-super/. Between the two sources I still have no clear idea of what super() will do and why it will doe what it does. I hope to get feedback that can be used as the basis to update the python docs. For single inheritance the use of super() does not seem to have any surprises. But in the case of a class with multiple-inheritance more then 1 function may be called by 1 call to super(). What are the rules for which functions are called by super() in the multiple inheritance case? Is __init__ special or can other super() calls end up calling more then 1 function? What is the role of **kwds with super()? Here is the code I used to show the __init__ multiple calls. The attached example shows that one call to super() causes 2 to __init__ of bases of Person. But describe does not follow the pattern Age.describe is not called. Barry

No, super() does not (directly) call multiple functions. The function it calls has to call the next with another super() call. Also, __init__() is not special, nor is **kwds. super() itself is special, it knows the class and instance. There are conventions around all of this though. It may be worth documenting those, as long as it is made clear which part of the docs is about conventions (as opposed to how things work). There are also opinions about those conventions. Here I am not so sure that they belong in the docs. --Guido (mobile) On Jul 2, 2016 10:32 AM, "Barry Scott" <barry@barrys-emacs.org> wrote:

On 2 Jul 2016, at 18:58, Guido van Rossum <gvanrossum@gmail.com> wrote:
No, super() does not (directly) call multiple functions. The function it calls has to call the next with another super() call. Also, __init__() is not special, nor is **kwds
The thing I do not understand is why did super() call 2 __init__ functions given the code I attached? The one in QObject and the one in Age. This is the output I get with python 3.5: $ python3.5 super_example.py instance of Person.__init__ instance of QObject.__init__ instance of Age.__init__ Person.describe() name: Barry QObject.describe() I see no obvious code that should call Age.__init__, which is why I concluded that there is something about super() that is not documented.
Agreed. Barry

The trick is in the mro. If you print Person.__mro__ you'll get a list showing that its MRO (method resolution order) is Person, QObject, Age, object. In Person, super() refers to QObject (the next class in the MRO). In QObject, *for a Person instance*, super() refers to Age. In Age, in this case, super() refers to object. The methods on object don't call super. Hope this helps -- you should be able to get more help by Googling for something like MRO. On Sat, Jul 2, 2016 at 11:45 AM, Barry Scott <barry@barrys-emacs.org> wrote:
-- --Guido van Rossum (python.org/~guido)

You should be able to get more help by Googling for something like MRO.
Raymond's pycon2015 talk is also a good way to understand everything involved. https://www.youtube.com/watch?v=EiOglTERPEo Mark Daoust On Sat, Jul 2, 2016 at 3:28 PM, Guido van Rossum <gvanrossum@gmail.com> wrote:

The MRO’s importance is what I managed to not understand from the super() docs. Now I understand that I can explain the behaviour of the code example. The existing docs say: "The search order is same as that used by getattr() except that the type itself is skipped.” But getattr does not document its search order so that does not help. "getattr(object, name[, default]) Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.” The MRO not mentioned, and not used? So do not mention? I think it would help anyone else that missed the point as I did to document exactly what super() does. In engineer English something like this. "super() uses the __mro__ as the order to search for the attribute to return. super() starts by finding the type in the __mro__ and then examines the following items until the attribute is found and returns it. If the attribute is not found AttributeError is raised.” Thoughts? Barry

On Tue, Jul 5, 2016 at 12:16 AM, Barry Scott <barry@barrys-emacs.org> wrote:
Nitpick: Instead of saying "the __mro__", I'd say something like "the Method Resolution Order (found in cls.__mro__)" first time and "the MRO" second. The MRO is a feature of the class; it happens to be made available in the attribute __mro__, but that's secondary. ChrisA

On Sat, Jul 2, 2016, at 14:45, Barry Scott wrote:
Because you called it twice. Well, actually three times: 1. Person calls super().__init__ which calls QObject.__init__. 2. QObject calls it *again*, which calls Age.__init__. 3. Age calls it again, which calls object.__init__, which does nothing and prints nothing. With each method you call, the named keywords are stripped off of **kwds; none of them are left by the time it gets to Age, so none are passed to object - otherwise you would get an error: TypeError: object.__init__() takes no parameters.

No, super() does not (directly) call multiple functions. The function it calls has to call the next with another super() call. Also, __init__() is not special, nor is **kwds. super() itself is special, it knows the class and instance. There are conventions around all of this though. It may be worth documenting those, as long as it is made clear which part of the docs is about conventions (as opposed to how things work). There are also opinions about those conventions. Here I am not so sure that they belong in the docs. --Guido (mobile) On Jul 2, 2016 10:32 AM, "Barry Scott" <barry@barrys-emacs.org> wrote:

On 2 Jul 2016, at 18:58, Guido van Rossum <gvanrossum@gmail.com> wrote:
No, super() does not (directly) call multiple functions. The function it calls has to call the next with another super() call. Also, __init__() is not special, nor is **kwds
The thing I do not understand is why did super() call 2 __init__ functions given the code I attached? The one in QObject and the one in Age. This is the output I get with python 3.5: $ python3.5 super_example.py instance of Person.__init__ instance of QObject.__init__ instance of Age.__init__ Person.describe() name: Barry QObject.describe() I see no obvious code that should call Age.__init__, which is why I concluded that there is something about super() that is not documented.
Agreed. Barry

The trick is in the mro. If you print Person.__mro__ you'll get a list showing that its MRO (method resolution order) is Person, QObject, Age, object. In Person, super() refers to QObject (the next class in the MRO). In QObject, *for a Person instance*, super() refers to Age. In Age, in this case, super() refers to object. The methods on object don't call super. Hope this helps -- you should be able to get more help by Googling for something like MRO. On Sat, Jul 2, 2016 at 11:45 AM, Barry Scott <barry@barrys-emacs.org> wrote:
-- --Guido van Rossum (python.org/~guido)

You should be able to get more help by Googling for something like MRO.
Raymond's pycon2015 talk is also a good way to understand everything involved. https://www.youtube.com/watch?v=EiOglTERPEo Mark Daoust On Sat, Jul 2, 2016 at 3:28 PM, Guido van Rossum <gvanrossum@gmail.com> wrote:

The MRO’s importance is what I managed to not understand from the super() docs. Now I understand that I can explain the behaviour of the code example. The existing docs say: "The search order is same as that used by getattr() except that the type itself is skipped.” But getattr does not document its search order so that does not help. "getattr(object, name[, default]) Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.” The MRO not mentioned, and not used? So do not mention? I think it would help anyone else that missed the point as I did to document exactly what super() does. In engineer English something like this. "super() uses the __mro__ as the order to search for the attribute to return. super() starts by finding the type in the __mro__ and then examines the following items until the attribute is found and returns it. If the attribute is not found AttributeError is raised.” Thoughts? Barry

On Tue, Jul 5, 2016 at 12:16 AM, Barry Scott <barry@barrys-emacs.org> wrote:
Nitpick: Instead of saying "the __mro__", I'd say something like "the Method Resolution Order (found in cls.__mro__)" first time and "the MRO" second. The MRO is a feature of the class; it happens to be made available in the attribute __mro__, but that's secondary. ChrisA

On Sat, Jul 2, 2016, at 14:45, Barry Scott wrote:
Because you called it twice. Well, actually three times: 1. Person calls super().__init__ which calls QObject.__init__. 2. QObject calls it *again*, which calls Age.__init__. 3. Age calls it again, which calls object.__init__, which does nothing and prints nothing. With each method you call, the named keywords are stripped off of **kwds; none of them are left by the time it gets to Age, so none are passed to object - otherwise you would get an error: TypeError: object.__init__() takes no parameters.
participants (5)
-
Barry Scott
-
Chris Angelico
-
Guido van Rossum
-
Mark Daoust
-
Random832