首页 > 解决方案 > 如何为需要比较同一类的自定义对象定义 __eq__ func

问题描述

我想__eq__()为自定义类实现一个方法Vertex

但是,当我仔细考虑这个问题时,我发现它很奇怪。

例如

class Vertex():
    def __init__(self,node):
        self.id = node
        self.adjacent = {}

但是对于相邻的dict,它存储这样的数据:

 {neighbour_vertex1 : edge, neighbour_vertex2 : edge, ....}

如果我想实现该__eq__()方法,它应该如下所示:

def __eq__(self,other):
    return self.id == other and self.adjacent == other.adjacent

self.adjacent == other.adjacent需要比较听写

 {neighbour_vertex1 : edge, neighbour_vertex2 : edge, ....}
 {neighbour_vertex1 : edge, neighbour_vertex2 : edge, ....}

为了比较它们,我必须定义neighbout_vertex确实是 class 实例的比较函数Vertex

我认为这就像一个先有鸡还是先有蛋的问题,任何建议都值得赞赏。

编辑:示例

 class Vertex(object):
    def __init__(self,id):
        self.id = id
        self.adjacent ={}

    def add_vertex(self,obj):
        self.adjacent.update(obj)

    def __eq__(self,other):
        return self.id == other.id and self.adjacent == other.adjacent

    def __hash__(self):
        return hash(id(self))


obj1 = Vertex("one")
obj2 = Vertex("two")
temp = {obj2:"connect 1-2"}
obj1.add_vertex(temp)

obj1s = Vertex("one")
obj2s = Vertex("two")
temp2 = {obj2s:"connect 1-2"}
obj1s.add_vertex(temp2)

if obj1 == obj1s:
    print("True")

else:
    print("False")

我拿出了一个简单的例子,首先我不想修改hash函数,如何修改__eq__函数让上面的代码输出 True而不是False

标签: pythonpython-3.x

解决方案


我认为您根本不需要在__eq__这里覆盖。Vertex使用您选择的设计,两个不同的实例表示“相同的顶点”是没有意义的,并且两个Vertex实例只有在它们实际上是同一个对象时才应该比较相等。默认__eq__实现已经为您提供了该行为。

如果您确实希望不同的实例Vertex比较相等,那么您需要首先考虑您的设计。例如,您对__hash__as的定义hash(id(self))仅在平等通过身份起作用时才有意义,因此您__hash__需要更改。你还需要考虑一些事情,如果顶点ab都有self.id = 1self.adjacent = {c: 'asdf'},但是cself.adjacent = {b: 'asdf'}怎么办?是ab平等的吗?你将不得不对你想要使用的平等概念提出一个精确的定义。

一种可能的重新设计是将邻接跟踪移出顶点对象。如果顶点对象只有self.id,并且边缘被某种 Graph 对象从外部跟踪,那么“按值”比较 Vertex 对象可能是有意义的。不过,到那时,完全消除 Vertex 类可能更有意义。


推荐阅读