Python Object-Oriented Python Inheritance Super!

Sarah Burgart
Sarah Burgart
2,409 Points

method on list called through super()

Not understanding why append() worked as expected and sort() did not?

inventory.py
class Inventory:
    def __init__(self):
        self.slots = []

    def add_item(self, item):
        self.slots.append(item)

class SortedInventory(Inventory):
    def __init__(self):
        super().__init__()

    def add_item(self, item):
        super(SortedInventory, self).add_item(item)
        self.slots.append(item)
        self.slots.sort()

3 Answers

Alex Koumparos
MOD
Alex Koumparos
Python Web Development Treehouse Moderator 32,453 Points

Hi Sarah,

Let's begin by eliminating some harmless but redundant code so we can focus on the problem area with your method.

SortedInventory doesn't extend or override any functionality from Inventory's __init__ method. Since subclasses automatically inherit their parent's methods and attributes (including __init__), we can omit the whole method.

Also note that when using super inside a method, you can omit the arguments, as the compiler will correctly retrieve the class and instance.

These changes would simplify your class to:

class SortedInventory(Inventory):

    def add_item(self, item):
        super().add_item(item)
        self.slots.append(item)
        self.slots.sort()

Now that our code is more readable, we can step through what your extended add_item method is doing when we call it.

We're going to assume for our illustration that we already have a SortedInventory object assigned to my_inv with the slots attribute being ['axe', 'health potion', 'shield'].

Here's our method call:

>>> my_inv.add_item('mana potion')

And we step through the execution of your method line by line:

  1. super().add_item(item)
    We're calling super, which Python looks up as Inventory. This means we are using Inventory's add_item method (but self still refers to my_inv):
    1.1. (inside Inventory.add_item) self.slots.append(item)
    We're appending item ('mana potion') to my_inv.slots. Thus, my_inv.slots is now ['axe', 'health potion', 'shield', 'mana potion'].
    We've reached the end of Inventory's version of the method, so we return back to SortedInventory's add_item method.
  2. self.slots.append(item)
    We're appending item ('mana potion') to my_inv.slots, so it is now ['axe', 'health potion', 'shield', 'mana potion', 'mana potion']
  3. self.slots.sort()
    We're using the sort method for lists to produce: ['axe', 'health potion', 'mana potion', 'mana potion', 'shield']

We can verify this by querying the slots attribute:

>>> my_inv.slots
['axe', 'health potion', 'mana potion', 'mana potion', 'shield']

Working through the code line by line, it should be clear that we are appending mana potion twice: once during the super call to Inventory and then again inside SortedInventory's own add_item method.

We can fix the code by removing the append line in your subclass's method. Remember, the reason that we are taking advantage of inheritance and extending the superclass's method (rather than simply writing a whole new independent class) is so that we can continue to rely on the superclass to perform its existing functionality (simply adding items to slots) but then add our own additional functionality after the superclass has done its thing (sorting the slots).

Hope that clears everything up for you.

Cheers

Alex

Brian Chalfant
Brian Chalfant
4,379 Points
super(SortedInventory, self).add_item(item)

This is where your problem lies. You don't need to call to super because your SortedInventory.add_item is already overriding your Inventory.add_item. Take that line out and it should work just fine.

Sarah Burgart
Sarah Burgart
2,409 Points

can't. it specifically says, "Bummer: You need to override add_item inside of SortedInventory. For now, just have it call super().

You can call the superclass add_item method under your own add_item using super()

def add_item(self, item):
        super().add_item(item)
Sarah Burgart
Sarah Burgart
2,409 Points

isn't that what I did?

def add_item(self, item): super(SortedInventory, self).add_item(item) self.slots.append(item) self.slots.sort()