Равенство классов Python с использованием слотов - PullRequest
6 голосов
/ 24 декабря 2010

Другой вопрос предоставляет хорошее, простое решение для реализации теста на равенство объектов.Я повторю ответ для контекста:

class CommonEqualityMixin(object):

    def __eq__(self, other):
        return (isinstance(other, self.__class__)
            and self.__dict__ == other.__dict__)

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

class Foo(CommonEqualityMixin):

    def __init__(self, item):
        self.item = item

Я хотел бы сделать это для класса, который использует __slots__.Я понимаю, что и базовый класс, и подкласс должны будут использовать слоты, но как бы вы определили __eq__ для этого для работы со слотами?

Ответы [ 2 ]

6 голосов
/ 24 декабря 2010
import operator

class CommonEqualityMixin(object):

    __slots__ = ()

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            if self.__slots__ == other.__slots__:
                 attr_getters = [operator.attrgetter(attr) for attr in self.__slots__]
                 return all(getter(self) == getter(other) for getter in attr_getters)

        return False

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

Пример использования:

class Foo(CommonEqualityMixin):
    __slots__ = ('a', )
    def __init__(self, a):
        self.a = a

Foo(1) == Foo(2)
# False
Foo(1) == Foo(1)
# True

Примечание: знайте, что __slots__ не наследуется, это не похоже на __dict__, так что если, например, новый класс FooBar наследуетFoo код выше не будет работать

Пример:

class FooBar(Foo):
    __slots__ = ('z')
    def __init__(self, a, z):
        self.z = z
        super(FooBar, self).__init__(a)

FooBar(1, 1) == FooBar(2, 1)
# True

print FooBar(1, 1).__slots__
# 'z'
1 голос
/ 20 сентября 2011

Джефф, вам следует подумать об использовании шаблона проектирования Flyweight, если вам необходимо отследить такое количество записей.

См .: http://codesnipers.com/?q=python-flyweights

На этой странице описывается ситуация, в которой многие из отслеживаемыхзаписи имеют одинаковые значения.В этом случае шаблон Flyweight чрезвычайно полезен.Тем не менее, это также очень полезно, когда записи имеют фактически уникальные значения.(в этом случае вы сохраняете значения в массиве / матрице и т. д. и оборачиваете хранилище в класс).

...