6

次のコードがあります。

a = str('5')
b = int(5)
a == b
# False

しかし、 のサブクラスを作成してint再実装すると、次のようになり__cmp__ます。

class A(int):
    def __cmp__(self, other):
        return super(A, self).__cmp__(other)
a = str('5')
b = A(5)
a == b
# TypeError: A.__cmp__(x,y) requires y to be a 'A', not a 'str'

なぜこの2つは違うのですか?Python ランタイムは、によってスローされた TypeError をキャッチしint.__cmp__()、それを値として解釈していFalseますか? これがどのように機能しているかを示す 2.x cpython ソースのビットを教えてもらえますか?

4

3 に答える 3

5

ドキュメントはこの点について完全に明示的ではありませんが、ここを参照してください。

両方とも数値の場合は、共通の型に変換されます。それ以外の場合、異なるタイプのオブジェクトは常に等しくなく、一貫して任意に順序付けられます。非組み込み型のオブジェクトの比較動作を制御するには、特殊なメソッド名セクションで説明されている__cmp__メソッドまたは のような豊富な比較メソッドを定義します。__gt__

これ (特に、「異なる型のオブジェクト」と「非組み込み型のオブジェクト」の間の暗黙の対比) は、実際に比較メソッドを呼び出す通常のプロセスが、組み込み型の場合はスキップされることを示唆しています: 2 つの異なる (および非数値の) 組み込み型である場合、自動 False に短絡するだけです。

于 2012-09-17T18:40:20.803 に答える
3

の比較決定木はa == b次のようになります。

  • python 呼び出しa.__cmp__(b)
    • ab適切なタイプであることを確認します
    • bが適切な型の場合-1、 、0、または+1
    • そうbでない場合は、戻りますNotImplented
  • -10、または返された場合+1、python は完了です。それ以外は
  • NotImplented が返された場合は、試してください
  • b.__cmp__(a)
    • ba適切なタイプであることを確認します
    • aが適切な型の場合-1、 、0、または+1
    • そうaでない場合は、戻りますNotImplemented
  • -10、または返された場合+1、python は完了です。それ以外は
  • NotImplented が再び返された場合、答えはFalse

正確な答えではありませんが、お役に立てば幸いです。

于 2012-09-17T18:49:14.123 に答える
-2

あなたの問題を正しく理解していれば、次のようなものが必要です。

>>> class A(int):
...     def __cmp__(self, other):
...         return super(A, self).__cmp__(A(other)) # <--- A(other) instead of other
... 
>>> a = str('5')
>>> b = A(5)
>>> a == b
True

更新しました

2.x のcpythonソースに関して、この結果の理由は、実際に 2 つのことをチェックtypeobject.cする関数で見つけることができます。wrap_cmpfuncfuncotherself

if (Py_TYPE(other)->tp_compare != func &&
    !PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) {
// ....
}
于 2012-09-17T18:17:57.407 に答える