如何修改子类的__init__方法中的继承列表?

时间:2014-04-20 04:05:44

标签: python inheritance init

是否可以在类的 init 函数中更改某些内容?

假设我有一个名为“deck”的类,它在初始化时会创建一个包含52个卡对象的列表。

现在我想创建一个名为“even”的类,它继承自“deck”类并创建一副卡片对象但是从继承的“套牌”中删除所有带有数字2的牌(所以黑桃,心脏等)

我遇到了很多麻烦,因为当我尝试修改继承的列表时,无论我尝试什么,python都会返回错误,通常将'NoneType'作为问题的主要根源。这是“偶数”类init的代码:

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

值得注意的是,我的卡类有一个方法rank(),它会将卡的等级作为int返回。

无论我尝试过哪些事情,总会出现问题。有时会说“'NoneType'对象不可迭代”或“可订阅”,当我检查x的type()时,它是NoneType。我已经做了很多搜索,但对于NoneType或我应该做些什么来解决它没有任何意义。

如果我删除for循环,那么代码将按预期创建一副52张牌,但我需要过滤掉2的牌。

编辑: 这是我的甲板课 init

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

如果你不能说,卡也是一个班级,甲板的 init 会创建52个卡片对象

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:1)

考虑到你在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__的值,该值本身将返回None作为好__init__应该。