I have a base class that represents the state of a game and provides a perform_move method:
class GameState:
# other code
def perform_move(self, position: LinePosition) -> MoveResult:
# more code
Now I want to create a subclass of GameState that keeps track of the players' score.
Because the base class doesn't care about players (separation of concerns), I need an additional argument to identify the player that is performing the move.
I tried the following:
class ScoreKeepingGameState(GameState):
# other code
def perform_move(self, position: LinePosition, *, player_identification: Optional[int] = None) -> MoveResult:
# more code
I expected this to work, since I can call ScoreKeepingGameState's perform_move perfectly fine without the player_identification, alas pylint complains:
W0221: Parameters differ from overridden 'perform_move' method (arguments-differ)
Is there a cleaner approach to satisfy pylint than adding # pylint: disable=arguments-differ to the perform_move definition of ScoreKeepingGameState?
There's some quick and direct ways, and then there's the way where you rethink the design and use of inheritance.
The quick way: Make perform_move in the base class accept *args and **kwargs arguments; then the inheriting class also just accepts *args and **kwargs and it all will work. I don't like it that much because we lose the function signature that way, but it will make pylint stop complaining.
The longer way: If GameState shouldn't concern itself with player scores, then I assume it has some other single responsibility. Subclasses of GameState will still have that same responsibility; they're just fulfilling it in a different way. But now you also make it responsible for calculating and keeping track of the player's score. At least I assume that's what the overriden version of perform_move is supposed to do.
So maybe you want a separate class ScoreKeeper just for tracking score, and it shouldn't inherit from GameState.
Then you'd have a class responsible for "handling" player moves. This class would communicate separately with GameState to tell it about the line position and with ScoreKeeper to tell it about the player.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With