Метод класса __instancecheck__ не работает
Я использую python 2.7.3 для Windows. Я попытался переопределить магический метод __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
должен взять класс/тип как второй параметр.
Кто-нибудь знает, в чем проблема? Спасибо.
Ответы
Ответ 1
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
должен быть классом класса, другими словами, метакласса!
Ответ 2
В документах говорится:
Обратите внимание, что эти методы проверяются на тип (метакласс) класса. Они не могут быть определены как методы класса в реальном классе. Это согласуется с поиском специальных методов, вызываемых экземплярами, только в этом случае экземпляр сам по себе является классом.
http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks