从传递的回调中访问实例

时间:2018-07-10 22:35:26

标签: python-3.x

我正在用python编写一个包含物品的游戏。玩家可以使用物品,不同的物品可以做不同的事情。我没有为每种项目类型创建一堆子类,而是在初始化时传递了回调函数。但是,在某些情况下,我需要从回调函数访问item实例-这就是我遇到的问题。

这就是我想要做的:

class Item:
    def __init__(self, use_callback, regen=0):
        self.use_callback = use_callback
        self.regen = regen

def heal(self, player):
    player.health += self.regen

item = Item(heal, regen=30)
item.use_callback(player)

但是,仅将播放器对象而不是item对象传递给了heal函数:TypeError: heal() missing 1 required positional argument

由于我正在使用item表,因此使用子类对我来说很不方便每个敌人都会掉落,其中包含有关掉落物品的信息,并且在死亡时实例化一个物品比弄清楚我需要实例化哪个子类要容易得多。

关于如何获取对项目对象的引用的任何想法?

1 个答案:

答案 0 :(得分:1)

如何包装回调以传递对象:

class Item:
    def __init__(self, use_callback, regen=0):
        self.use_callback = lambda *args, **kwargs: use_callback(self, *args, **kwargs)
        self.regen = regen

def heal(item, player):
    if item.regen is not None:
       player.health += item.regen

item = Item(heal, regen=30)
item.use_callback(player)

Example code

我会考虑考虑的另一种体系结构是让Player对象具有消费方法。这样做的好处是可以从Item对象中消除复杂性。可能有一种稍微整洁的方式来编写此代码。

item = Item(effects=[(heal, regen=30), (gravity_boost, multiplier=2), (speed)])
class Player
    def consume(self, item):
        for effect in item.effects:
            callback = effect[0]
            **kwargs = effect[1:]
            callback(player, item, **kwargs)

除此之外,可能值得考虑使用一个简单的“发布订户”系统,该系统将您的对象分开,以使它们不会具有交叉依赖性。这将以增加一些代码复杂性为代价来增加体系结构的简单性。