I have to model a warrior and the different kinds of attacks he can perform. The idea is to use mixins to contain the attack logic. I have my classes defined in the following way:
class Warrior: def __init__(self, energy): self.energy = energy class TemplarKnight(Warrior, HandToHandCombatMixin): pass class CombatMixin: def __init__(self): self.attacks_cost = {} def attack(self, attacker, attack_cost): if attacker.energy < attack_cost: print('Not enough energy to attack') else: attacker.energy -= attack_cost print('Attack!') class HandToHandCombatMixin(CombatMixin): def __init__(self): super().__init__() self.attacks_cost['sword_spin'] = 10 def sword_spin(self, attacker): return self.attack(attacker, self.attacks_cost['sword_spin']) But the problem comes when I try to test this setup. When I do
class TestTemplarKnight(unittest.TestCase): def setUp(self): self.templar = TemplarKnight(energy=100) def test_templar_knight_can_sword_spin(self): self.templar.sword_spin(self.warrior) self.assertEquals(self.templar.energy, 90) I get
def sword_spin(self, attacker): return self.attack( > attacker, self.attacks_cost['sword_spin']) E AttributeError: 'TemplarKnight' object has no attribute 'attacks_cost' It seems that Python thinks that the parameter self.attacks_cost (when calling self.attack() inside the sword_spin() method of the HandToHandCombatMixin class) belongs to the TemplarKnight class instead of the HandToHandCombatMixin.
How should I have written this code to make Python look for self.attacks_cost inside HandToHandCombatMixin?
__init__methods in this case should be usingsuper().__init__method that sets them gets called.