定义时部分确定参数的Python的解决方法?

时间:2018-10-02 03:20:48

标签: python python-3.x functools

我一直在开发一款基于纸牌的格斗游戏来练习Python编码,并且我为玩家和纸牌提供了对象。创建卡片时,我一直在使用functools.partial为每个卡片对象分配功能,到目前为止,这种功能一直在起作用:

from functools import partial

class Player(object):
    def __init__(self):
        self.health = 100
    def play_card(self, card):
        card.ability(player=self)

human = Player()
computer = Player()
human.opponent = computer
computer.opponent = human

class Card(object):
    def __init__(self, ability):
        self.ability = ability

def attack(amount, player):
    player.opponent.health -= amount

working_card = Card(partial(attack, 8))
human.play_card(working_card)

这显然是代码的极大简化版本,但这是重要的部分。当我调用human.play_card(working_card)时,human Player对象将执行play_card(card = working_card)函数,然后该函数将激活working_card.ability()局部函数,从而启动Attack(amount = 8,player = human)函数。

但是随后,我引入了一个变量作为部分函数的参数之一,如下所示:

broken_card = Card(partial(attack, player.health))
human.play_card(broken_card)

partial函数试图确定首次创建Card对象时(不知道什么是“ player”)时player.health的值。我希望它改为在调用Attack(Amount,Player)时(即“ Player”具有含义时)确定Player.Health的值。我尝试使用lambda并将attack()函数放置在Card对象内没有成功,并且在Internet上找不到此类问题的任何答案。我需要一些方法来解决部分尝试确定首次调用player.health的问题,如果不是显式的话,还可以通过重构代码逻辑的工作方式来解决。

1 个答案:

答案 0 :(得分:1)

您可以使用lambda代替partial来推迟参数的评估:

broken_card = Card(lambda *args, **kwargs: attack(player.health, *args, **kwargs))

请记住,player必须与定义此lambda的范围相同。然而。由于player恰好是attack的第二个参数,因此您可以使lambda使用已知参数:

broken_card = Card(lambda player: attack(player.health, player))