Принадлежность объекта к наборам

Это на самом деле два вопроса:

  1. Почему никогда не вызывается оператор членства (__contains__)?

  2. Почему D есть в nodeList, а не в nodeSet?

Моя цель состоит в том, чтобы D был «в» как nodeList, так и nodeSet, потому что он имеет тот же loc, что и A.

class Node(object):
    def __init__(self, loc):
        self.loc = loc

    def __eq__(self, other):
        print "eq: self.getLoc(): {}, other.getLoc(): {}".format(self.getLoc(),     other.getLoc())
        if self.getLoc() == other.getLoc():
            return True
        return False

    def __contains__(self, other):
        print "contains: self.getLoc(): {}, other.getLoc(): {}".format(self.getLoc(),  other.getLoc())
        if self.getLoc() == other.getLoc():

            return True
        return False

    def setLoc(self, loc):
        self.loc = loc

    def getLoc(self):
        return self.loc


if __name__ == "__main__":
    A = Node((1,1))
    B = Node((2,2))
    C = Node((3,3))

    D = Node((1,1))

    nodeList = [A, B, C]
    nodeSet = set()
    nodeSet.add(A)
    nodeSet.add(B)
    nodeSet.add(C)

    print "A in nodeList: {}".format(A in nodeList)
    print "A in nodeSet: {}".format(A in nodeSet)
    print "D in nodeList: {}".format(D in nodeList)
    print "D in nodeSet: {}".format(D in nodeSet)

Это возвращает True, True, True, False. По-видимому, оператор __contains__ никогда не вызывается. Я хотел бы, чтобы он возвращал True, True, True, True.

Любая другая критика моего кода, конечно, приветствуется, так как я новичок в Python.


person user1287170    schedule 22.03.2012    source источник
comment
1. __contains__ вызывается, когда вы спрашиваете объект, есть ли в нем другой объект. Здесь вызывается метод __contains__ nodeList и nodeSet, а не Node.   -  person Casey Kuball    schedule 23.03.2012
comment
См. этот ответ. Короче говоря, вам нужно определить __hash__, если вы хотите, чтобы D in nodeSet возвращало True. Кроме того, мы обычно не используем геттеры и сеттеры, если они не необходимы (что бывает относительно редко).   -  person DSM    schedule 23.03.2012
comment
@DSM, и тогда вы используете свойства, а не геттеры и сеттеры.   -  person Katriel    schedule 23.03.2012
comment
@DSM - Большое спасибо за ваш ответ и ссылку, это мне очень помогло.   -  person user1287170    schedule 23.03.2012


Ответы (2)


См. документацию по __hash__() — вкратце:

[I]f [класс] определяет __cmp__() или __eq__(), но не __hash__(), его экземпляры нельзя будет использовать в хешированных коллекциях.

set — это хешированная коллекция. Вы должны убедиться, что реализуете Node.__hash__()

person Kristian Glass    schedule 23.03.2012
comment
Хотя то, что вы пишете, верно, реальная проблема автора плаката заключается в том, что contains реализован в неправильном классе. - person James Youngman; 23.03.2012
comment
Ах, я пропустил это, спасибо, но это должно по крайней мере ответить на их второй вопрос. - person Kristian Glass; 23.03.2012

Зачем вообще Node.__contains__ вызывать? У вас никогда не будет Node в правой части выражения in.

person Marcin    schedule 22.03.2012