Python dice类,返回单个骰子

2024-06-06 11:27:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个Die()类,其中有一个dice shaker()子类。DiceShaker()子类应该获取Die()类的多个副本,对它们进行掷骰,然后返回单个骰子。这是我的Die()代码。在

class Die(object):
 'a class representing a Die'
  def __init__(self, sides=6):
     'initialize a die, default 6 sides'
      self.sides = sides

 def roll(self):
     'roll the dice'
      self.dieRoll = random.randint(1, self.sides)


 def get(self):
     'get the current value of the die'
      return self.dieRoll

这是我的掷骰子()的代码。在

^{pr2}$

getIndividualRolls()应该返回一个列表,其中包含通过shake()传递的所有骰子,但打印的列表始终只有一个数字。 示例:

d=DiceShaker(3)
d.shake()
[None, None, None]
d.getIndividualRolls()
[3, 3, 3]

我让shake()返回[none],这样我就知道骰子的数目是正确的,但是我不明白为什么getIndividualRolls()总是打印出重复的结果。谁能帮我弄清楚我做错了什么吗?在


Tags: the代码selfnonedef骰子dice子类
2条回答

您的DieShaker类应该只是Die对象列表的包装器。在

class Die(object):
    'a class representing a Die'
    def __init__(self, sides=6):
        'initialize a die, default 6 sides'
        self.sides = sides
        # You should make sure that by the time someone has created a Die object, 
        # all the attributes they might want to access have been defined
        self.roll()

   def roll(self):
       'roll the dice'
        self.dieRoll = random.randint(1, self.sides)

   # Note I got rid of Die.get 
   # Anyone who can call Die.get can see Die.dieRoll

class DiceShaker(object):
    def __init__(self, dice=()): # Note we avoid mutable default arguments
        self.dice = list(dice)   # Presumably it would be nice to add/remove dice

    def shake(self):
        for die in self.dice:
            die.roll()
        # return self.get_dice() 
        # It doesn't really make sense for this to return anything

    def get_dice(self):
        return [die.dieRoll for die in self.dice]

这将是太长的评论:

顺便说一句,您应该真正学习Python3。python2是on the way out。下面的一切都在python3中运行。在

为什么你的DiceShakerDie的子类?这没道理。子类化用于is a关系。DiceShaker不是Die的类型(就像ShoppingCart不是{}的类型一样)。你的关系很复杂。DiceShakerDies(你用你的dieList反映出来)。在这种情况下,dieList就是您所需要的。您不需要从Die继承。在

你得到同样数量的骰子的根本原因是因为你继承了死亡。通过子类化Die,您使DiceShaker的行为类似于Die。这意味着您可以调用ds.roll()ds.get()(其中ds = DiceShaker()),并且它的行为与在Die上调用它的行为完全相同。这实际上就是您在编写Dice.get(self)时所做的工作。这相当于self.get()(因为DiceShaker扩展了Dice)。但是DiceShaker只是一个Die,而不是多个。因此调用get()将始终返回相同的结果。您有效地完成了以下工作:

die = Die()
die.roll()

for other_die in self.dieList:
    self.dieList2.append(die.get())  # note you're getting the same die each time

所以要解决这个问题,您不需要从Die继承。事实上你不应该。而是组合DieShaker和{}。这意味着DieShaker应该委托给它包含的Die(通过对它们调用get,而不是自身)。在

^{pr2}$

注意,在get_values_rolled(相当于你的DieShaker.getIndividualRolls)中,我们如何对我们的振荡器包含的每个Die调用{}(相当于你的Die.get)。在

还请注意,我通过以下方式清理了您的代码:

  • Python中的惯例是将snake_case用于变量/属性和函数
  • 我重命名了一些函数以使它们的关系更清晰(get_value_rolled和{})
  • 我使用了list comprehensions(例如[Die(num_die_sides) for _ in range(num_die)]与while循环相同,append指向你的{},但更像Python)
  • 我将while替换为for。通常在python中,当您使用iterables(listlist)时,您希望使用for。在
  • 我删除了DieShaker构造函数的一些可选参数。就你的目的而言,允许它们被传递是没有多大意义的(如果你想涉足更具技术性的领域,你这样做是有原因的,但现在就你的目的而言,不要这样做)。看起来您可能认为您需要将所有内容都作为__init__的参数,但实际上不是这样

坏的:

def __init__(self, num_die=1, die_sides=6, dice = []):
    self.dice = dice

您可能应该这样做:

def __init__(self, num_die=1, die_sides=6):
    self.dice = []
  • 我删除了你的第二份名单。您只需要维护一个die列表(因为在每个die上调用roll()之后,它将每次为get_value()返回相同的内容)

相关问题 更多 >