2011-01-29 77 views
1

这是我到目前为止有:为什么我不能有一个可变参数构造函数和另一个带有固定参数的构造函数?

class Die (object): 
    def __init__(self,sides): 
     self.sides = sides 

    def roll(self): 
     return random.randint(1,self.sides) 

    def __add__(self,other): 
     return Dice(self,other) 

    def __unicode__(self): 
     return "1d%d" % (self.sides) 

    def __str__(self): 
     return unicode(self).encode('utf-8') 

class Dice (object): 
    def __init__(self, num_dice, sides): 
     self.die_list = [Die(sides)]*num_dice 

    def __init__(self, *dice): 
     self.die_list = dice 

    def roll(self): 
     return reduce(lambda x, y: x.roll() + y.roll(), self.die_list) 

但是,当我尝试做Dice(3,6),并随后致电roll动作它说,它不能因为'int' object has no attribute 'roll'。这意味着它首先进入可变参数构造函数。我能做些什么来完成这项工作,还是有另一种选择?

+0

它不会“首先进入可变参数构造函数”。在类定义中,所有方法都是唯一的,在那里没有两个构造函数(它们实际上是初始化函数)。你的`die_list`是一个通过整数的元组。 – SilentGhost 2011-01-29 20:42:12

回答

3

正如你在你的问题观察到的,可变参数的构造函数被调用。这是因为Dice.__init__的第二个定义是重写,而不是重载,第一个。

Python doesn't support method overloading,所以你至少有两种选择。

  • 仅定义可变参数构造函数。检查参数列表的长度和前几个元素的类型以确定要运行的逻辑。实际上,您会将这两个构造函数合并为一个。
  • 将其中一个构造函数转换为静态工厂方法。例如,您可以删除第一个构造函数,保持可变参数,然后定义新的工厂方法。

我更喜欢第二种方法,它允许你干净地分离你的逻辑。您还可以为工厂方法选择更具描述性的名称; from_n_sided_dice不仅仅是Dice更多的信息:

@staticmethod 
def from_n_sided_dice(num_dice, sides): 
    return Dice([Die(sides)] * num_dice) 

边注:这真的是你想要的吗? [Die(sides)] * num_dice返回一个带有对同一个Die对象的多个引用的列表。相反,你可能想要[Die(sides) for _ in range(num_dice)]

编辑:您可以emulate method overloading(通过动态调度,你也可以使用,但静态类型不会在Python存在不是静态调度)功能与装饰。您可能必须设计自己的解决方案来支持*args**kwargs,并且使用更精确的名称进行单独的方法通常是更好的解决方案。

+0

OP的代码中的所有`Die`对象都是无状态的,所以同一个`Die`的N个副本应该产生与N个不同的`Die`对象相同的结果。 – 2011-01-29 21:02:47

1

你想拥有什么是一个__init__法,即沿着这些线路定义:

class Dice (object): 
    def __init__(self, *args): 
     if not isinstance(args[0], Die): 
      self.die_list = [Die(args[0]) for _ in range(args[1])] 
     else: 
      self.die_list = args 
    def roll(self): 
     return sum(x.roll() for x in self.die_list) 
+0

Yohr当前的构造函数有时会使`self.die_list`成为一个元组,并且会使其他时间成为一个列表。我会尽量让它每次都是一样的。 – 2011-01-29 21:12:41

相关问题