【问题标题】:Sharing Class Variables共享类变量
【发布时间】:2013-12-21 02:48:23
【问题描述】:

这是我的意思的一个非常简短的例子。

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(我实际使用的),这还不是全部,还有两个其他(甚至更大的)系统比我需要实施(技能和津贴)。因此,如果我要依赖子类,我会在一个庞大的类中加载子类,而不是稍后在代码中组合许多类。

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

编辑/更新:另请注意,此代码将被多次重复用于许多不同的变量,而不仅仅是一个(当然。)

【问题讨论】:

  • 有很多方法可以解决这个问题。我发现最明显的一个是没有class2 处理method2;将逻辑移到知道必要对象的地方,例如class3
  • @user2357112 就像我说的,我“认为”这是不可行的,但既然你提到它,“链接”它可能会起作用,尽管它会使代码更加复杂。 (例如,声明一个在 class2 中使用 class1 的变量,然后在 class4 中使用 class2 和 class3,依此类推,而不是像我现在那样尝试在 4 类中合并 1、2 和 3 类)

标签: python class methods instance


【解决方案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)

【讨论】:

  • 虽然它没有直接回答我的问题,但我认为……这仍然非常有用,我从中学到了很多东西。谢谢!但是在某种程度上,我确实认为您的“目标”系统确实主要回答了我的问题,所以我会接受它作为答案:)
  • 哦,没关系,真正回答的是你如何创建“角色”类,然后在分支中继续使用“怪物(角色)”和“魔术师(角色)”类,这就是我选择的方式无论如何都要继续我的代码。做了一些小的修改,但我认为现在看起来好多了。再次感谢!
  • 我看到您的代码与典型的面向对象方法有不同的方法,因此我想展示如何以这种方式进行操作。另外,请记住,您还可以将MagicianMonster 子类化,就像您对Character 进行子类化一样。例如:class Dragon(Monster),然后是class Whelp(Dragon): ...,从上往下不断细化。
  • 另外,为了一些额外的帮助,我添加了一个 mixin 示例
  • 我已经重写了一些原始代码块以使用您向我展示的继承系统。继承非常适合我正在做的事情(尽管我偶尔会使用组合)。 Mixins 对我来说也是全新的,非常感谢您指出这一点,毫无疑问它很快就会被证明是有用的。你帮了我很多^_^。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
相关资源
最近更新 更多