16

Windowsでpython 2.7.3を使用しています。__instancecheck__マジックメソッドをクラスメソッドとしてオーバーライドしてみました。しかし、私はそれを機能させることはできません。

class Enumeration(int):
    @classmethod
    def __instancecheck__(cls, inst):
        if type(inst) == cls:
            return True
        if isinstance(inst, int) and inst in range(0,10):
            return True
        return False

print isinstance(1, Enumeration)   # prints False
print isinstance(1, Enumeration()) # prints True

最初の print ステートメントは True になると思います。しかし、魔法のメソッド__instancecheck__は呼び出されていないようです。isinstanceそして、2番目のパラメーターとしてクラス/タイプを取る必要があるため、2番目のprintステートメントが機能する理由がわかりません。

誰が問題が何であるか知っていますか?ありがとう。

4

2 に答える 2

22

instancecheckメタクラスで定義する必要があります:

class Enumeration(type):
    def __instancecheck__(self, other):
        print 'hi'
        return True


class EnumInt(int):
    __metaclass__ = Enumeration

print isinstance('foo', EnumInt) # prints True

何故ですか?2番目の例が機能したのと同じ理由で。Python が評価するとき、それはオブジェクトであるisinstance(A, B)と想定し、そのクラスを探し、そのクラスを呼び出します。B__instancecheck__

isinstance(A, B):
    C = class-of(B)
    return C.__instancecheck__(A)

しかし、Bがクラス自体である場合、そのクラスCはクラスのクラス、つまりメタクラスである必要があります。

于 2012-10-30T09:12:57.380 に答える
7

ドキュメントは言う:

これらのメソッドは、クラスの型 (メタクラス) で検索されることに注意してください。実際のクラスでクラス メソッドとして定義することはできません。これは、インスタンスで呼び出される特別なメソッドのルックアップと一致していますが、この場合のみ、インスタンス自体がクラスです。

http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks

于 2012-10-30T09:09:51.947 に答える