Прямой ответ будет состоять в использовании typing.Union
и намека на:
Union[HumanPlayer, IAPlayer]
Однако это означает, что переданный объект может иметь любые признаки либо класс. Пока оба класса реализуют один и тот же интерфейс, это не имеет значения. Но трудно держать оба класса в syn c просто по соглашению, поэтому вам следует подумать о формальном способе помочь этому процессу, используя общий родительский класс. ABC
очень полезен в этом отношении:
from abc import ABC, abstractmethod
class Player(ABC):
def something_common(self):
# do something common
@abstractmethod
def play(self):
"""Players must implement their specific play style."""
raise NotImplementedError
...
class HumanPlayer(Player):
def play(self):
# play humanely
def care_for_bodily_needs(self):
# take a break
Теперь вы можете смело намекать на Player
и его четко определенный интерфейс. Если HumanPlayer
или IAPlayer
реализуют что-то, чего нет у другого, это не будет включено в интерфейс Player
и, следовательно, не может безопасно использоваться внутри вашей функции play_game
, делая ваш тип кода безопасным.
def play_game(player1: Player, player2: Player):
player1.something_common()
player1.play()
player2.play()
def ensure_is_comfortable(player: HumanPlayer):
player.care_for_bodily_needs() # only safe to call here