2013-12-21 148 views
0

下面是我的意思的一个非常简短的例子。共享类变量

class class1(): 
    def method1(self): 
     self.variable1 = 5 
class class2(): 
    def method2(self): 
     self.variable2 = var1.variable1 * 2 
class class3(): 
    def __init__(self): 
     self.var1 = class1() 
     self.var2 = class2() 

instance = class3() 
instance.var1.variable1 = 10 
instance.var2.method2() 
print instance.var2.variable2 

上面的代码显然会停在倒数第二行,因为class2不知道var1是什么。

现在我知道这样的事情是可行的与子类,或者只是保持所有在同一类中的方法。但在我的情况下,我不认为(我不是说我知道,因为我不是很有经验,但我不认为)这是一个可行的解决方案。

这里是一个bigger sample code(我实际上在做什么),这不是全部,有2个其他(甚至更大)的系统比我需要实现(技能&特技)。所以如果我依赖于子类,我会有一个大型的类加载子类,而不是稍后在代码中加入的许多类。

有什么好方法可以解决这个问题?我只是做这一切都错了吗?

编辑/更新:另外要注意,这个代码将被重新多次使用了很多不同的变量,而不是一个(当然)

+0

有许多的方式来解决这个问题。我发现最明显的是没有'class2'处理'method2';将逻辑移动到某个知道必要对象的地方,比如'class3'。 – user2357112

+0

@ user2357112像我说的,我“认为”这是不可行的,但现在你提到它,“链接”它可能有效,尽管它会使代码更加复杂。 (例如声明一个变量,它在class2中使用class1,然后在class4中使用class2和class3,等等,而不是像我现在正在做的那样尝试合并class 4中的class 1,2和3) – Cestarian

回答

1

也许是这样的:

class NotEnoughMagic(Exception): 
    pass 


class Character(object): 
    fire = 0 
    magic = 0 
    hp = 100 
    armor = 1 
    def take_damage(self, amount): 
     self.hp -= amount 
     if self.hp <= 0: 
      print '%s HAS DIED!' % type(self).__name__ 
    def walk(self): 
     pass 
    def attack(self, target, attack_points): 
     target.take_damage(attack_points/target.armor) 


class Monster(Character): 
    fire = 50 
    hp = 150 
    armor = 2 
    def punch(self, target): 
     self.attack(target, 25) 


class Magician(Character): 
    magic = 10 
    def magic_armor(self): 
     self.hp += 20 
     self.magic -= 10 
    def sword_attack(self, target): 
     self.attack(target, 20) 
    def magic_attack(self, target): 
     """Does tons of damage but uses all magic""" 
     if self.magic > 0: 
      self.attack(target, 100) 
      self.magic = 0 
     else: 
      raise NotEnoughMagic() 

用法:

>>> monster  = Monster() 
>>> magician = Magician() 
>>> 
>>> print magician.hp 
100 
>>> print monster.hp 
150 
>>> 
>>> monster.punch(magician) 
>>> magician.sword_attack(monster) 
>>> 
>>> print magician.hp 
75 
>>> print monster.hp 
140 
>>> 
>>> monster.punch(magician) 
>>> magician.magic_attack(monster) 
>>> 
>>> print magician.hp 
50 
>>> print monster.hp 
90 
>>> 
>>> monster.punch(magician) 
>>> magician.magic_attack(monster) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 14, in magic_attack 
__main__.NotEnoughMagic 
>>> 
>>> print magician.hp 
25 
>>> print monster.hp 
90 
>>> 
>>> monster.punch(magician) 
Magician HAS DIED! 
>>> magician.sword_attack(monster) 
>>> 
>>> print magician.hp 
0 
>>> print monster.hp 
80 

一些潜在的游戏逻辑:

>>> # Gang of monsters 
... monsters = [Monster() for x in range(10)] 
>>> magician = Magician() 
>>> 
>>> # Prepare for battle 
... while magician.magic > 0: 
...  magician.magic_armor() 
...  
... # Put on some chain mail 
... magician.armor += 5 
    File "<stdin>", line 6 
    magician.armor += 5 
     ^
SyntaxError: invalid syntax 
>>> 
>>> 
>>> while magician.hp > 0: 
...  for m in monsters: 
...    m.punch(magician) 
... 
Magician HAS DIED! 
Magician HAS DIED! 
Magician HAS DIED! 
Magician HAS DIED! 
Magician HAS DIED! 
Magician HAS DIED! 
Magician HAS DIED! 
>>> 

更新:

此外,有一点需要注意的是mixins。例如,如果您想要将更多功能添加到一组广泛的类中,而不是在整个继承树下。

class TeleportAbilityMixin(object): 
    def teleport(self, destination): 
     cost = 20 
     if self.mp >= cost: 
      # Unpack the x, y coordinates 
      self.x, self.y = destination 
      self.mp -= cost 

class TeleportingMagician(Magician, TeleportAbilityMixin): 
    pass 

m = TeleportingMagician() 
new_location = (10, 5) 
m.teleport(new_location) 
+0

虽然它不直接回答我的问题,我认为...这仍然是非常有用的,我从中学到了很多东西。谢谢! 在某种程度上,不过,我觉得你的“目标”在系统主要回答我的问题,所以我会接受它作为一个答案:) – Cestarian

+1

哦没关系,真正回答它是如何创建的“性格”类,然后继续在“怪物(人物)”和“魔术师(人物)”课程的分支中,这就是我选择继续使用我的代码的方式。进行了一些小修改,但我认为现在看起来好多了。再次感谢! – Cestarian

+0

我看到你的代码与典型的面向对象的方法有不同的方法,所以我想展示一下如何以这种方式做到这一点。另外,请记住,您也可以按照分类为“Character”的方式来划分“魔术师”或“怪物”。例如:“龙类(怪物)”,然后是“龙类(龙)”:......并从顶部进一步细化。 –