我试图使用DiceShaker()子类创建一个Die()类。 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
这是我的DiceShaker()代码。
class DiceShaker(Die):
'DiceShaker class'
def __init__(self,dieCount=1, dieSides=6, dieList = [], dieList2 = []):
'initialize a dice shaker'
Die.__init__(self,sides = 6)
self.dieCount = dieCount
self.dieSides = dieSides
self.dieList = dieList
self.dieList2 = dieList2
def shake(self):
'shake all the dice in the shaker'
counter = 0
dieList = []
while counter != self.dieCount:
self.dieList.append(Die.roll(self))
counter = counter + 1
return self.dieList
def getIndividualRolls(self):
'get a lsit of integers of all the individual die rolls'
for items in self.dieList:
self.dieList2.append(Die.get(self))
return self.dieList2
getIndividualRolls()应返回一个列表,其中包含通过shake()传递的所有骰子,但打印的列表始终只是一个数字。 示例:
d=DiceShaker(3)
d.shake()
[None, None, None]
d.getIndividualRolls()
[3, 3, 3]
我摇晃()返回[none]只是因为我知道正确数量的骰子正在经历,但我无法弄清楚为什么getIndividualRolls()会继续打印出重复数据。任何人都可以帮我弄清楚我做错了什么吗?
答案 0 :(得分:1)
这对于评论来说太长了:
顺便说一句,你应该学习Python 3. Python 2是on the way out。下面的所有内容都适用于Python 3。
为什么您的DiceShaker
是Die
的子类?这毫无意义。子类化用于is a
关系。 DiceShaker
不是Die
的类型(就像ShoppingCart
不是CartItem
的类型)。你的关系是有组织的。 DiceShaker
有Die
个(您用dieList
反映)。在这种情况下,dieList
就是您所需要的。您无需继承Die
。
您获得相同数字的根本原因是因为您从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
和Die
。这意味着DieShaker
应该委托给它所包含的Die
(通过调用get
,不是)。
from random import randint
class Die:
def __init__(self, sides=6):
self.sides = sides
def roll(self):
self._rolled_value = randint(1, self.sides)
def get_value_rolled(self):
return self._rolled_value
class DieShaker:
def __init__(self, num_die=1, num_die_sides=6):
self.dice = [Die(num_die_sides) for _ in range(num_die)]
def shake(self):
for die in self.dice:
die.roll()
def get_values_rolled(self):
return [die.get_value_rolled() for die in self.dice]
请注意get_values_rolled
(相当于您的DieShaker.getIndividualRolls
),我们在每个get_value_rolled
上调用Die.get
(相当于您的Die
)我们的振动器包含的内容(在列表self.dice
)。
另请注意,我通过以下方式清理了您的代码:
snake_case
用于变量/属性和函数get_value_rolled
和get_values_rolled
)[Die(num_die_sides) for _ in range(num_die)]
与append
self.dieList
对你的while
的while循环相同,但更为pythonic)for
替换为for
。通常在python中,当你使用iterables(list list
)时,你想使用DieShaker
。__init__
构造函数的一些可选参数。为了你的目的,允许它们被传入是没有多大意义的(如果你想涉及更多的技术,你有理由这样做,但为了你的目的,不要) 。您可能认为自己需要将所有内容作为def __init__(self, num_die=1, die_sides=6, dice = []):
self.dice = dice
的参数,但事实并非如此。而不是这个(实际上是has a serious issue unrelated to the style/semantics):为:
def __init__(self, num_die=1, die_sides=6):
self.dice = []
你可能应该这样做:
roll()
get_value()
之后,每次都会为schemas
返回相同的东西)答案 1 :(得分:0)
您的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]