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

我假设第一个打印语句会得到 True。但似乎__instancecheck__没有调用魔术方法。而且我不知道为什么第二个打印语句可以工作,因为它isinstance应该将类/类型作为第二个参数。

有谁知道问题是什么?谢谢。

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

这是为什么?出于同样的原因,您的第二个示例有效。当 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 回答