The "Who's Next" List

Let's say:

  1. For each class, we arrange all superclasses into an ordered list without repetitions, and insert the class itself at the start of the list. We put this list in an class attribute called next_class_list for our use later.

    Example 2.3. Making a "Who's Next" list

    B.next_class_list = [B,A]
    
    C.next_class_list = [C,A]
    
    D.next_class_list = [D,B,C,A]
    
    

  2. We use a different technique to implement do_your_stuff() for our classes.

    Example 2.4. Call next method technique

    class B(A):
        def do_your_stuff(self):
            next_class = self.find_out_whos_next()
            next_class.do_your_stuff(self)
            # do stuff with self for B
    
        def find_out_whos_next(self):
            l = self.next_class_list           # l depends on the actual instance
            mypos = l.index(B)  1            # Find this class in the list
            return l[mypos+1]                  # Return the next one
    
    
    

    The interesting part is how we find_out_whos_next(), which depends on which instance we are working with. Note that:

    • Depending on whether we passed an instance of D or of B, next_class above will resolve to either C or A.

    • We have to implement find_out_whos_next() for each class, since it has to have the class name hardcoded in it (see 1 above). We cannot use self.__class__ here. If we have called do_your_stuff() on an instance of D, and the call is traversing up the hierarchy, then self.__class__ will be D here.

Using this technique, each method is called only once. It appears clean, but seems to require too much work. Fortunately for us, we neither have to implement find_out_whos_next() for each class, nor set the next_class_list, as Python does both of these things.