Programmer's Python - Single Inheritance
Written by Mike James   
Monday, 06 August 2018
Article Index
Programmer's Python - Single Inheritance
Basic Inheritance
Overriding
Super Super and the mro

 

Notice that the search doesn’t include the class specified i.e. the search of the mro for the attributes starts at the class after the one you specify.

What this means is that the default:

super()

used without arguments within a class C is converted to:

super(C,this)

by default.

If you use super outside of a class or if you don’t want to use the default then you have to provide arguments to the call to super().

For example:

class A:
    myAttribute=42
class B(A):
    myAttribute=43
class C(B):
    myAttribute=44
class D(C):
    myAttribute = 45
    def myMethod(self):
      print("class D")
      print(self.myAttribute)
      print(super().myAttribute)
      print(super(D, self).myAttribute)
      print(super(C, self).myAttribute)
      print(super(B, self).myAttribute)

The inheritance is as before:

A → B → C → D

and each class defines its own myAttribute but set to 42, 43, 44 and 45 respectively.

The method in class D uses variations on accessing myAttribute to demonstrate how super() works.

If you try:

d=D()
d.myMethod()

Then you will see 45, 44, 44, 43, and 42 printed.

First notice that as in all of the calls to super, self is a reference to d, then the mro used in all of the calls is the same i.e. type(self).__mro__ which is D.__mro__ i.e.

(<class '__main__.D'>, <class '__main__.C'>,
<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

The first reference to myAttribute is the standard one self.myAttribute and this uses the usual search order of D → C → B → A and it finds myAttribute in D and so we see 45.

The second uses the default form of super() and it is the same as super(D,self), the same as the third so they both use D.__mro__ miss D out of the search, and find the attribute in C and so both print 44.

The fourth uses super(C,self) and so uses D.__mro__ but starting the search at one on from C, finds the attribute in B and so prints 43 and finally super(B,self) uses the same __mro__ but hence starts its search in A and so prints 42.

It is as simple as that.

So to summarize, the call:

super(class,self)

retrieves the __mro__ from the class:

type(self)

and starts the search for the attributes at the next class in the __mro__ and if it finds it uses self to bind it.

You can see that super and the __mro__ is a flexible and sophisticated mechanism that almost reduces to the way super is used in other languages when called without arguments from within a class. It is important to realize at the very least that super() isn’t just a reference to the next class up the inheritance chain.

We need to look more closely at the mro as when we allow multiple inheritance as things become a little more complicated.

Inheriting Instance Attributes

Final version  in book

Do We Need to Use super?

Final version in book

Customizing Subclassing

Final version in book

Metaclass Inheritance

Final version in book

Summary

  • Inheritance is at its most basic about code reuse.

  • Object oriented programming has a number of different philosophies that attempt to motivate its use. The most common is that classes should model the real world – the domain model.

  • The domain model has to be hierarchical because single inheritance creates class hierarchies; the problem is that the world isn’t a simple hierarchy.

  • The four pillars of object oriented programming are classes, inheritance, encapsulation and polymorphism.

  • Python allows multiple inheritance but you can restrict your use of it to single inheritance if you want to.

  • Inheritance in Python is a simple extension of the way attributes are resolved – first the instance is searched, then the class, then the base class, and then its base class, and so on until the attribute is located.

  • Attributes can be overridden by simply defining them in the class that inherits.

  • The super() built-in function can be used to return an attribute from the first class in the inheritance chain to define it.

  • The inheritance chain is defined in the class __mro__ attribute.

  • Super works by searching the __mro__ for the first class to define the method. You can specify the class that has the __mro__ to use and the starting class for the search.

  • If you restrict yourself to single inheritance then you can dispense with super() and access the attribute directly, but with multiple inheritance this simple approach doesn’t work.

  • Metaclasses can also be part of an inheritance chain and there are rules for which metaclass is used.

 

Programmer's Python
Everything is an Object
Second Edition

Is now available as a print book: Amazon

pythonObject2e360

Contents

  1. Get Ready For The Python Difference
  2. Variables, Objects and Attributes
  3. The Function Object
  4. Scope, Lifetime and Closure
      Extract 1: Local and Global ***NEW!
  5. Advanced Functions
  6. Decorators
  7. Class, Methods and Constructors
      Extract 1: Objects Become Classes 
  8. Inside Class
  9. Meeting Metaclasses
  10. Advanced Attributes
  11. Custom Attribute Access
  12. Single Inheritance
  13. Multiple Inheritance
  14. Class and Type
  15. Type Annotation
  16. Operator Overloading
  17. Python In Visual Studio Code

 Extracts from the first edition

<ASIN:1871962749>

<ASIN:1871962595>

<ASIN:1871962765>

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy


espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner

<ASIN:1871962587>

 



Last Updated ( Monday, 06 August 2018 )