2011-01-29 35 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

相關問題