2

我正在创建一个双链接结构,并且在比较两个节点是否相等时遇到了一些问题。该结构相当复杂,因为它具有多个属性,包括名称、行、列、右、左、上和下。如果两个节点相等,它们必须就所有这些属性达成一致。我知道在我的eq方法中,我可以简单地硬编码检查每个属性与另一个属性,但我认为会有一种更简单的方法来做到这一点,并找到了一种在大多数情况下都有效的方法。因此,我有以下内容:

def __init__ (self,row,col,name=None,up=None,down=None,left=None,right=None):
    self.name  = name
    self.row   = row
    self.col   = col
    self.up    = up
    self.down  = down
    self.left  = left
    self.right = right

def __eq__ (self, other):
    return vars(self) == vars(other)

以及对此并不重要的各种其他方法。所以我确定是否两个节点的捷径基本上是查看它们变量的字典,然后让 python 比较两个字典的等价性。

这很好用!只要两个节点实际上相等。它返回 True,然后我继续愉快地使用我的代码。但是如果两个节点实际上不相等,它就会分崩离析。我明白了

File "*filename*", line 35 in __eq__ return vars(self) == vars(self) 

在屏幕上写了无数次,直到它最终说

RuntimeError: maximum recursion depth exceeded

我知道有一些方法可以解决这个问题,即我可以显式检查每个属性,但这很糟糕,我想知道为什么这不起作用,以及是否可以轻松修复。我已经用其他更简单的字典测试了这种方法并且它有效,所以我的想法是这个问题与确定对象是否相等有关,但我不知道我可以在这里做什么。我意识到我也可以只做一个错误捕获然后让它返回 False 但除了这两个解决方案之外的其他解决方案将不胜感激,

4

2 回答 2

2

看起来您的 up、down 等都指向您班级的其他实例。

您的比较代码基本上是说,要测试 self == other,self.up == other.up 吗?self.up.up == other.up.up 吗?等等,然后递归直到空间用完。

您可能想要使用

def __eq__(self, other):
    return self.name == other.name \
        and self.row == other.row \
        and self.col == other.col \
        and self.up is other.up \
        and self.down is other.down \
        and self.left is other.left \
        and self.right is other.right
于 2012-07-13T18:07:23.797 回答
1

我手头没有python,但我想这就是发生的事情:

in the __dict__ofself和 in the __dict__ofother是对您的一个节点的引用,现在比较该节点是否相等(一旦一个来自 vars,一个来自另一个),这会导致调用您的比较方法。

如果您现在有一个循环(例如公共父级),您将获得无限递归:

self.parent在原始比较中:比较other.parent

self.parent.child在父比较中:比较other.parent.child

parentchild参考您的upand down

尝试(未经测试):

def __eq__(self, other):
    for s, o in zip(vars(self),vars(other)):
        if not s is o and s != o:
            return False

    return True

基本上是 Hugh Bothwell 的建议,只是循环。首先检查内存中是否有相同的对象,如果有,请不要比较它们,否则测试。

于 2012-07-13T18:10:44.843 回答