Как принять дополнительный параметр в подклассе? (Без аргументов Пилинт-отличаются) - PullRequest
1 голос
/ 16 января 2020

У меня есть базовый класс, который представляет состояние игры и предоставляет метод perform_move:

class GameState:
  # other code
  def perform_move(self, position: LinePosition) -> MoveResult:
    # more code

Теперь я хочу создать подкласс GameState, который отслеживает игроков Гол. Поскольку базовый класс не заботится об игроках (разделение интересов), мне нужен дополнительный аргумент, чтобы определить игрока, выполняющего ход. Я попробовал следующее:

class ScoreKeepingGameState(GameState):
  # other code
  def perform_move(self, position: LinePosition, *, player_identification: Optional[int] = None) -> MoveResult:
    # more code

Я ожидал, что это сработает, так как я могу назвать ScoreKeepingGameState perform_move совершенно нормально без player_identification, увы Пилинт жалуется:

W0221: параметры отличаются от переопределенного метода 'execute_move' (arguments-Different)

Есть ли более чистый подход для удовлетворения pylint, чем добавление # pylint: disable=arguments-differ к определению perform_move ScoreKeepingGameState

1 Ответ

1 голос
/ 16 января 2020

Есть несколько быстрых и прямых способов, а затем есть способ переосмыслить дизайн и использование наследования.

Быстрый способ: заставить perform_move в базовом классе принять *args и **kwargs аргументы; тогда наследующий класс также просто принимает *args и **kwargs, и все это будет работать. Мне это не очень нравится, потому что таким образом мы теряем сигнатуру функции, но это заставит Пилинта перестать жаловаться.

Более длинный путь: если GameState не должен касаться очков игроков, то я Предположим, у него есть какая-то другая ответственность. Подклассы GameState будут по-прежнему нести такую ​​же ответственность; они просто выполняют это по-другому. Но теперь вы также возлагаете на него ответственность за подсчет и отслеживание очков игрока. По крайней мере, я предполагаю, что именно это и должна делать переопределенная версия perform_move.

Так что, возможно, вам нужен отдельный класс ScoreKeeper только для отслеживания оценки, и он не должен наследоваться от GameState.

Тогда у вас будет класс, отвечающий за "обработку" ходов игрока. Этот класс будет взаимодействовать отдельно с GameState, чтобы сообщить ему о позиции линии, и с ScoreKeeper, чтобы сообщить об игроке.

...