2016-09-10 2 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 инициализируется 52 объектами Card Card (от 0, 0) до (3, 13). Почему он не обнаруживает это с помощью модуля удаления? Кроме того, после инициализации я могу выполнить следующие команды, и это работает без проблем.

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 экземпляр равен, если и когда оба rank и suit равны, то реализовать этот тест:

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__ определена. Этот код создает два отдельных экземпляра и без специального метода __eq__ два отдельных экземпляра никогда не тестируются как равные.

Вы, скорее всего, сделал это вместо:

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

, потому что только тогда будет тестируемый объект равным; это, в конце концов, тот же объект.

Смежные вопросы