4

__cmp__クラスの等価性を(メソッドを介して)再定義する既存のコードを使用しています。期待どおりに機能せず、修正しようとすると、理解できない動作に遭遇しました。__cmp__組み込み関数を呼び出すだけのクラスで定義するcmpと、常に最大の再帰深度に達すると予想されます。ただし、クラスのインスタンスをそれ自体と比較しようとすると、0 が返されます。

コードは次のとおりです。

class A:
    def __cmp__(self, other):
        return cmp(self, other)

a = A()
b = A()
cmp(a, a) # returns 0
cmp(b, b) # returns 0
cmp(a, b) # results in RuntimeError: maximum recursion depth exceeded

cmpRuntimeError はわかりましたが、最初の 2 つの呼び出しが成功する理由がわかりません。

Python ドキュメントのデータ モデルセクションや、 Python の等価性のこの素晴らしい内訳のようなものを読みましたが、この再帰に対する答えが見つかりません。

そして、はい、書かれているように、これはまったく無意味なクラスであることを理解しています. 私が取り組んでいるコードは、特定の状況で平等を再定義しようとし、それ以外の場合はベースケースに落ちます。ベースケースは実装どおりに機能しないため、修正しようとしています。通話cmpが機能する可能性があると考え、この問題を発見しました。これを理解することが、適切な解決策を見つけるのに役立つことを願っています。

4

3 に答える 3

1

2 つの名前が同じオブジェクトを参照する場合、それらは定義上等しいです ( edit : 少なくともcmp関係する限り、「等しい」とは実際には「より大きくも小さくもない」という意味です)。

于 2013-08-02T16:34:57.333 に答える
1

のセマンティクスでcmpは、比較されるオブジェクトが順序関係を持っている必要があるため (つまり、cmp(x, y)呼び出しx < yで 、x == y、または のいずれかが真であるx > y)、cmp引数がそれ自体と等しいと仮定し、比較メソッドの呼び出しをスキップすることができます。引数は同じオブジェクトです。

x(Python の多くのことは、任意のオブジェクトに対して,を想定していますx == x。これは、(特に NaN 浮動小数点値で) バグを引き起こすことがありますが、ほとんどの場合、これは便利な最適cmpcmpですx == x。への前提条件cmp(x, x)。)

于 2013-08-02T16:36:00.503 に答える