【问题标题】:Multi-Classing with a Custom Object and Emulating Container Types使用自定义对象进行多分类并模拟容器类型
【发布时间】:2015-03-12 16:03:14
【问题描述】:

实际示例:所以我有一个六面骰子 (d6),我将与其他 3 个骰子一起放入 4 个六面骰子 (4d6)。当然,我可以一次掷出 1d6,但我宁愿“同时”掷出 4d6。

这是我的component.py 模块,它包含一个组件类。这本身基本上是一个空类(它有一个 name 属性),所以这不应该影响这个问题的其余部分:

class Die(Component):

    def __init__(self, sides=6, start=1, stop=6):
        super(Die, self).__init__()
        self.sides = sides
        self.start = start
        self.stop = stop

    def roll(self):
        die_range = self.stop - self.start + 1
        result = randrange(self.start, self.stop, die_range/self.sides)
        return result

我希望最终能够在 game.py 脚本中写出与此类似的内容,如下所示:

from component import Dice

my_dice = Dice(count=4)
my_dice.append(Dice(count=3, sides=12, stop=12))
print(my_dice.roll())

我希望输出看起来像:

4, 2, 3, 1, 7, 12, 8

我远较少担心使输出看起来不错。我可以弄清楚;我刚刚给出了完整的上下文。

这就是我为Dice 类写的内容:

class Dice(Die, object):
    def __init__(self, container=None, count=0, **kwargs):
        super(Dice, self).__init__()
        if container is None:
            container = []
        if kwargs is not None:
            for x in range(count):
                container.append(Die(**kwargs))

        self.container = container

    def append(self, item):
        if hasattr(item, 'container'):
            self.container.extend(item.container)
        elif issubclass(item, Die):
            self.container.append(item.container)
        else:
            raise Exception(TypeError)

    def __str__(self):
        return str(self.container)

    def __repr__(self):
        return str(self.container)

    def __getitem__(self, key):
        return Dice(self.container[key])

    def __len__(self):
        return len(self.container)

    def roll(self):
        results = []
        for die in self.container:
            results.append(die.roll())
        return results

这是好的设计吗?我不相信它是这样或那样的。

如果有人对该应用程序感兴趣,我正在构建一个桌面游戏框架,并且我想要其他人可以轻松子类化的通用类,以使他们的游戏更快。

【问题讨论】:

  • 我认为你将 Dice 附加到 Dice 的事实似乎很尴尬......这是你的意图吗?我认为这是有意义的扩展而不是追加
  • @user3012759,这很好。让我用更好的方法更新那个方法。

标签: python methods subclass


【解决方案1】:
  • 首先,我认为,像 Die as Dice 那样使用如此接近的类名是令人困惑且容易出错的。我会选择 Die & DiceSet。

    class Dice(Die, object):
    
  • 我不明白 Dice 从 Die 继承了什么,它真的需要继承它吗?

    if hasattr(item, 'container'):
        self.container.extend(item.container)
    
  • 看起来不可靠,所以某个具有“容器”的类的每个对象都将被添加到 Dice 容器中...检查它是否是 Dice 的子类会更好吗?

    elif issubclass(item, Die):
        self.container.append(item.container)
    
  • 我认为这是一些复制粘贴的错字,因为 Die 不应该有任何容器,所以只需 append(item)

     result = randrange(self.start, self.stop, die_range/self.sides)
    
  • 我不确定步长的计算。步长不应该是分数。我认为它应该总是“1”:

    result = randrange(self.start, self.stop, 1)
    
  • 和边数无关。您只需要它来检查 startstop 是否小于 sides。当然,您缺少对 start 小于 stop 的检查。您可以使用 sides 来默认初始化 stop(如果没有给出)。

  • 您可以将 Die 的最后结果存储为 Die 的私有属性:将其初始化为 startDie 中的随机值。__init__(由设计),然后将其保存在 roll 中。所以你可以覆盖 Die 中的表示:

    def __repr__(self):
         print str(self.last_result)
    

然后修改 Dice 的表示:

    def __repr__(self):
         print ','.join(self.container)

所以打印 Dice 对象时会得到一组数字。

【讨论】:

  • @raiderrobert 这对你有意义吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多