Я думаю, что PEP описания __instancecheck__()
неисправна. PEP 3119 говорит:
Основной механизм, предложенный здесь, чтобы перегружать встроенные функции isinstance() и issubclass(). Перегрузка работает следующим образом: вызов isinstance (x, C) сначала проверяет, существует ли C.__instancecheck__
, и если да, то вызовы C.__instancecheck__(x)
вместо обычной реализации.
Вы можете написать:
class C:
def do_stuff(self):
print('hello')
C.do_stuff(C())
Так на основе приведенной выше цитаты из PEP, вы должны быть в состоянии написать
class C:
@classmethod
def __instancecheck__(cls, x):
print('hello')
C.__instancecheck__(C())
--output:--
hello
Но isinstance() не вызывает этот метод:
class C:
@classmethod
def __instancecheck__(cls, y):
print('hello')
x = C()
isinstance(x, C)
--output:--
<nothing>
Затем PEP продолжает:
Эти методы предназначены для называться по классам, чьи метакласса является (на основе) ABCMeta ...
Хорошо, давайте попробуем, что:
import abc
class MyMeta(abc.ABCMeta): #A metaclass derived from ABCMeta
def __instancecheck__(cls, inst):
print('hello')
return True
class C(metaclass=MyMeta): #A class whose metaclass is derived from ABCMeta
pass
x = C()
C.__instancecheck__(x)
--output:--
hello
Но еще раз isinstance() не называет этот метод:
isinstance(x, C)
--output:--
<nothing>
Заключение: PE P 3119 необходимо переписать вместе с документами Data Model.
Это связано с (но не дубликат): http://stackoverflow.com/questions/13135712/class-method-instancecheck-does-not-work – dnozay