2014-04-20 53 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。