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): 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.
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)
B is a class itself, then its class
C should be a class of a class, in other words, a meta-class!
The docs say:
Note that these methods are looked up on the type (metaclass) of a class. They cannot be defined as class methods in the actual class. This is consistent with the lookup of special methods that are called on instances, only in this case the instance is itself a class.