2014-04-20 71 views
1

有沒有可能改變init函數的一些東西?如何修改子類的__init__方法中的繼承列表?

可以說我有一個名爲「deck」的類,它在初始化時會創建一個包含52個卡片對象的列表。

現在我想創建另一個叫做「偶數」的類,它繼承了「甲板」類並創建了一副卡片對象,但是從繼承的「卡片組中刪除了所有具有數字2的卡片」。

我一直有很多麻煩,因爲當我嘗試修改繼承列表時,無論我嘗試什麼,python都會返回一個錯誤,通常以'NoneType'爲主要問題的根源。下面是「連」類初始化代碼:

def __init__(self): 
    x = Deck.__init__(self) 
    for card in x: 
     if card.rank() == 2: 
      x.pop(card) 
    return x 

值得注意的是,我的卡類有一個方法,秩(),這將返回紙牌的等級爲int。

無論我嘗試過的所有事情,總會有些問題。有時它會說「'NoneType'對象不可迭代」或「可下標」,當我檢查x的類型()時,它是一個NoneType。我已經做了大量的搜索,但對我來說沒有任何關於NoneType或我應該做什麼來解決它。

如果我刪除了for循環,那麼代碼將按照預期創建一個包含52張卡片的卡片組,但我需要過濾掉2個卡片。

編輯: 這是我的甲板類初始化

class Deck(list): 
    def __init__(self): 
     return list.__init__(self, [Card(i) for i in range(52)]) 

如果你不能告訴,卡也是一類和甲板的初始化將創建52個對象

+2

'__init__''返回None,這會導致錯誤消息。你能證明卡片是如何存儲在基類中的嗎?或者,像「Deck.get_even_cards」這樣的函數可能更適合代替繼承。 –

+0

嗯,我需要有「甲板」作爲我的基礎班。這與繼承它是一回事嗎?作爲你的基類和繼承有相同的東西嗎? – frosty

+1

@frosty:請顯示您的'Deck'類(或至少它的__init__')的代碼。你應該做的是直接修改'self'屬性,但怎麼做取決於'Deck'如何存儲數據。 – BrenBarn

回答

3

因此,假設一個簡單版本的Deck基類,繼承修改存儲在基類中的卡片列表,可以這樣做:

# simple baseclass that contains a list of Card objects 
class Deck(object): 
    def __init__(self): 
     self.deck = [...] # some list of cards 

# a class to hold only even cards 
class Even(Deck) 
    def __init__(self): 
     # use super to instantiate the baseclass 
     super(Even,self).__init__(self) 

     # create a local instance of `deck` that contains only even cards 
     # the base set of cards can still be acessed via super(Even,self).deck 
     self.deck = [card for card in self.deck if card.rank() != 2] 

編輯:更新對問題的補充信息:

class Deck(list): 
    def __init__(self): 
     super(Deck,self).__init__([Card(i) for i in range(52)]) 

class Even(Deck) 
    def __init__(self): 
     super(Even,self).__init__(self) 
     [self.remove(card) for card in self if card.rank()==2] 
0

鑑於方式,你正在做的事情在Deck,你會在你的子類中做的是:

def __init__(self): 
    Deck.__init__(self) 
    self[:] = [card for card in self if card.rank() != 2] 

由於您的對象從list繼承,因此它是一個列表,因此您可以通過直接分配到一個片來對其進行修改。

但是,這可能不是設計你的班級的最佳方式。而不是從list繼承,通常更容易在內部存儲列表並修改它以執行所需操作。

請注意,您不應該從__init__返回任何東西。 __init__不返回對象的值;它應該修改self來設置它想要的,並且總是返回None。您在Deck中返回的唯一原因是您返回超類__init__的值,該值超過__init__應返回None。