使用插槽的Python类的相等性

gae*_*fan 6 python equality class slots

另一个问题提供了一个很好的,简单的解决方案,用于实现对象相等的测试.我将重复上下文的答案:

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
Run Code Online (Sandbox Code Playgroud)

我想为一个使用的类做这个__slots__.我知道基类和子类都必须使用插槽,但是你如何定义__eq__插槽呢?

mou*_*uad 7

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)
Run Code Online (Sandbox Code Playgroud)

用法示例:

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

Foo(1) == Foo(2)
# False
Foo(1) == Foo(1)
# True
Run Code Online (Sandbox Code Playgroud)

注意:请注意__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'
Run Code Online (Sandbox Code Playgroud)