Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

class method __instancecheck__ does not work

Tags:

python

I am using python 2.7.3 on Windows. I tried to override the __instancecheck__ magic method as a class method. But I can not make it work.

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

I assume the first print statement would get True. But it seems the magic method __instancecheck__ is not called. And I don't know why the second print statement can work since the isinstance should take a class/type as the second parameter.

Does anyone know what the problem is? Thanks.

like image 627
adarliu Avatar asked Oct 30 '12 09:10

adarliu


1 Answers

instancecheck must be defined in a metaclass:

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


class EnumInt(int):
    __metaclass__ = Enumeration

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

Why is that? For the same reason why your second example worked. When python evaluates isinstance(A, B) it assumes B to be an object, looks for its class and calls __instancecheck__ on that class:

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

But when B is a class itself, then its class C should be a class of a class, in other words, a meta-class!

like image 118
georg Avatar answered Oct 10 '22 18:10

georg