2013-03-10 17 views
10

Występuje problem polegający na dodawaniu instancji do zestawu, a następnie testowaniu w celu sprawdzenia, czy ten obiekt istnieje w tym zestawie. Zastąpiłem numer __eq__(), ale nie został on wywołany podczas testu integracji. Czy zamiast tego muszę zastąpić __hash__()? Jeśli tak, to jak zaimplementować __hash__(), biorąc pod uwagę, że muszę mieszać krotkę, listę i słownik?Jak wdrożyć __eq__ dla zestawu testu integracji?

class DummyObj(object): 

    def __init__(self, myTuple, myList, myDictionary=None): 
     self.myTuple = myTuple 
     self.myList = myList 
     self.myDictionary = myDictionary 

    def __eq__(self, other): 
     return self.myTuple == other.myTuple and \ 
      self.myList == other.myList and \ 
      self.myDictionary == other.myDictionary 

    def __ne__(self, other): 
     return not self.__eq__(other) 

if __name__ == '__main__': 

    list1 = [1, 2, 3] 
    t1 = (4, 5, 6) 
    d1 = { 7 : True, 8 : True, 9 : True } 
    p1 = DummyObj(t1, list1, d1) 

    mySet = set() 

    mySet.add(p1) 

    if p1 in mySet: 
     print "p1 in set" 
    else: 
     print "p1 not in set" 
+0

Może mógłbyś napisać test jednostkowy dla nas, który spodziewałbyś się osiągnąć sukces? Dostaję 'p1 w zestawie' z twoim kodem. Czy powinienem dostać coś innego? – hughdbrown

+2

hashing zmienne obiekty nie jest dobrym pomysłem ... – mgilson

+0

Zobacz http://wiki.python.org/moin/DictionaryKeys, dlaczego @mgilson ma rację. – delnan

Odpowiedz

10

Z documentation on sets:

Zajęcia są realizowane z wykorzystaniem słowników zestaw. W związku z tym wymagania dla elementów zestawu są takie same, jak dla słów słownika ; mianowicie, że element definiuje oba __eq __() i __hash __().

Podpowiedź __hash__ function documentation sugeruje łączenie skrótów składników. Jak wspominają inni, to nie jest ogólnie dobry pomysł, aby hash zmienny przedmiotów, ale jeśli naprawdę potrzebujesz, to działa:

class DummyObj(object): 

    ... 

    def __hash__(self): 
     return (hash(self.myTuple)^
       hash(tuple(self.myList))^
       hash(tuple(self.myDictionary.items()))) 

I sprawdzając, czy to działa:

p1 = DummyObj(t1, list1, d1) 
p2 = DummyObj(t1, list1, d1) 
mySet = set() 
mySet.add(p1) 

print "p1 in set", p1 in mySet 
print "p2 in set", p2 in mySet 

Drukuje :

$ python settest.py 
p1 in set True 
p2 in set True 
-3

Dobrze, moje przypuszczenie byłoby __eq__ lub __ne__ nie mogą nazywany przez pytona przy porównywaniu obiektów za pomocą „in” operatora. Nie jestem pewien, jaki byłby konkretny operator "bogatego porównania", patrząc na dokumentację, ale przesłonięcie __cmp__ powinno rozwiązać problem, ponieważ pyton używa go domyślnie do porównywania obiektów, jeśli nie jest zaimplementowany bardziej odpowiedni operator "bogatego porównania". .

+1

Mylisz się. '__eq__' i' __ne__' działają dobrze, problemem jest brak (niestandardowej, poprawnej) funkcji skrótu. – delnan

+0

Dlaczego miałbyś odpowiedzieć, jeśli po prostu zgadujesz? – Alan

Powiązane problemy