python-3.xsubclassing

Python 3 inheritance attribute not found


I am learning Python through a project and am running into an issue with subclassing. Based on everything I have read the process is pretty straightforward, but calls from the sub class to methods from the base class result in attribute not found errors.

My code sample includes the pertinent parts of the base class(Player), the subclass(Roster) and the setup and calls to the base and sub classes. What am I missing? Also is it necessary to create an init method in the subclass if it really isn't needed?

main script:

from battleship.player import Player, Roster

player=Player()
roster=Roster()

player.register()
roster.load_other_players()

Classes:

class Player:
    def __init__(self):
        ....
        self.getOtherPlayers = {}

    def register(self):
        ...
        return

    def get_other_players (self):
        return self.getOtherPlayers

    def gameFlow(self):
        if self.currentFlow != undefined:
            self.currentFlow+=1
        else:
            self.currentFlow = 0

    def setMove(self, m):
        return move.setMove(m);

class Roster(Player):
    def __init__(self):
        super().__init__()

    def load_other_players(self):
        print("Roster!!!")
        print("Other players: ", super.get_other_players())

Return:

Roster!!!
Traceback (most recent call last):
  File "player.py", line 23, in <module>
    roster.load_other_players()
  File "/home/jspooner/projects/battleship/BotPlayer/battleship/player.py", line 152, in load_other_players
    print("Other players: ", super.get_other_players())
AttributeError: type object 'super' has no attribute 'get_other_players'

Edit If anyone references this question in the future my actual problem was a design issue where I created an instance of the base class as well as an instance of the sub class. As a result I had 2 instances of related classes that weren't tied to each other.

To fix this I swapped the hierarchy so that Roster is the parent class and Player is the child. My main creates an instance of Player which naturally creates a related Roster class.


Solution

  • To address your primary question/issues: super is not a valid entity, it would be the function super(). Alternatively, since Roster inherits from Player, self.get_other_players() would also be an acceptable way of referencing this, since all of the superclass's properties are incorporated as the subclass.

    __init__ does not need to be explicitly created if it isn't necessary, but it IS necessary if you want to perform some initialization. It's worth reading THIS answer to get more in-depth information about what is actually going on with __init__ and why it is necessary.

    To answer a question that you didn't ask: Python is different than some other languages in a few ways, most notably the usage of getters and setters isn't necessary. Rather than super().get_other_players() or equivalent, just access the getOtherPlayers property directly. It is more elegant, makes for less lines of code and is easier to read/debug when you're maintaining your code (it's more 'pythonic')