2

二重にリンクされた構造を作成していますが、2 つのノードが等しいかどうかの比較で問題が発生しています。名前、行、列、右、左、上、下などの複数の属性を持つという点で、構造はかなり複雑です。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)

そして、これにはそれほど重要ではない他のさまざまな方法。したがって、2 つのノードが基本的にそれらの変数の辞書を見て、Python に 2 つの辞書の等価性を比較させるかどうかを判断するための近道です。

これはうまくいきます!2 つのノードが実際に等しい限り。これは True を返し、コードを楽しく進めます。しかし、2 つのノードが実際に等しくない場合、バラバラになります。私は得る

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

最終的に言うまで、画面に何度も書き込まれます

RuntimeError: maximum recursion depth exceeded

これにはいくつかの方法があることはわかっています。たとえば、各属性を明示的にチェックすることはできますが、それは不十分であり、なぜこれが機能しないのか、簡単に修正できるかどうかを知りたいのです。私はこの方法を他のより単純な辞書でテストしましたが、うまくいくので、問題はオブジェクトが等しいかどうかを判断することに関係していると思いますが、ここで何ができるかわかりません。エラー キャッチを実行して False を返すようにすることもできますが、これら 2 つの解決策以外の方法があれば幸いです。

4

2 に答える 2

2

上、下などは、クラスの他のインスタンスを指しているようです。

あなたの比較コードは基本的に、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はノードの 1 つへの参照です。これで、このノードが等しいかどうかが比較されます (1 回は vars からのもの、もう 1 回は他のノードからのもの)。これにより、比較メソッドが呼び出されます。

ループ (共通の親など) がある場合、無限再帰が発生します。

元の比較: とself.parent比較other.parent

親比較: とself.parent.child比較other.parent.child

(parentと とをchild参照)updown

試してください(未テスト):

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

基本的に、ヒュー・ボスウェルが提案したことを、ただのループで。最初にメモリ内に同じオブジェクトがあるかどうかを確認します。ある場合は比較せず、そうでない場合はテストします。

于 2012-07-13T18:10:44.843 に答える