Подтвердить что ты не робот

Метод класса __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 должен взять класс/тип как второй параметр.

Кто-нибудь знает, в чем проблема? Спасибо.

4b9b3361

Ответ 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