2016-09-10 116 views
3

下面是一些测试代码来描述我的问题。我已经创建了两个类别如下...无法从另一个对象的列表中删除对象

class Card: 
    def __init__(self, suit, rank): 
     self.suit = suit 
     self.rank = rank 

class Deck: 
    def __init__(self): 
     self.cards = [] 
     for suit in range(4): 
      for rank in range(13): 
       card = Card(suit, rank) 
       self.cards.append(card) 

d = Deck() 
d.cards.remove(Card(1, 1)) 

最后删除命令后,我得到以下错误:

Traceback (most recent call last): 
    File "<pyshell#111>", line 1, in <module> 
    d.cards.remove(Card(1, 1)) 
ValueError: list.remove(x): x not in list 

有谁知道这是为什么发生?我可以确认d对象被从(0,0)到(3,13)的总共52个Card对象初始化。为什么它没有使用删除模块检测到这一点?此外,我可以在初始化后执行以下命令,并且没有问题。

d.cards.append(Card(1, 1)) 
d.cards.remove(Card(1, 1)) 

这增加了,然后删除刚添加到列表中的卡,但它不会删除使用相同的值初始化卡。

+0

给你的'Card'类一个'__eq__'方法。 –

回答

5

您没有定义何时两个Card实例相等。没有这样的定义,list.remove()找不到任何相等的东西(obj1 == obj2为真)。自定义类的默认实现仅在对象为相同时(完全相同的对象,reference1 is reference2为真)时才相等。

__eq__ method添加到您的班级,以定义对于Card实例的等同含义。

例如,如果两个Card情况下是相等的,如果当两个ranksuit相等,则执行该测试:

def __eq__(self, other): 
    if not isinstance(other, Card): 
     return NotImplemented 
    return self.rank == other.rank and self.suit == other.suit 

现在list.remove()可以发现,测试等于传递了一个第一对象采用该方法。

需要注意的是:

d.cards.append(Card(1, 1)) 
d.cards.remove(Card(1, 1)) 

离不开定义__eq__工作。该代码创建两个单独的实例,并且没有自定义方法,两个单独的实例永远不会相等。

你最有可能这样做,而不是:

card = Card(1, 1) 
d.cards.append(card) 
d.cards.remove(card) 

,因为只有这样才能保证测试对象作为平等的;它毕竟是相同的物体