Python类型提示以匹配不同的类和常见的行为

2024-09-28 21:33:14 发布

您现在位置:Python中文网/ 问答频道 /正文

大家好我在找 输入暗示我的函数的最佳方法是,我希望接受不同类型的类,但具有相同的行为。 例如:

class HumanPlayer:
    pass

class IAPlayer:
    pass

def play_game(player1, player2)
    pass

如何为player1player2添加类型提示,以支持这两种播放器? 当然,我可以使用object或创建父类Player。但我确信这不是正确的解决方案


Tags: 方法函数game类型playobjectdefpass
2条回答

一种解决方案是为这两个类添加一个公共祖先,并将其用作类型提示:

class PlayerMixin:
    pass

class HumanPlayer(PlayerMixin):
    pass

class AIPlayer(PlayerMixin):
    pass

def play_game(player1: PlayerMixin, player2: PlayerMixin)
    pass

直截了当的答案是使用typing.Union和提示反对:

Union[HumanPlayer, IAPlayer]

但是,这意味着传递的对象可能具有任何类的特征。只要两个类实现同一个接口,这就无关紧要了。但仅仅按照惯例很难使两个类保持同步,所以您应该考虑一种正式的方法,通过使用共享父类来帮助实现这一过程。在这方面^{}非常有用:

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及其定义良好的接口。如果HumanPlayerIAPlayer实现了另一个没有实现的东西,那么它将不会包含在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

相关问题 更多 >