Есть возможность удовлетворить первую часть или требование.Но для этого потребуется вспомогательный класс .MySubClass является потомком типа, MySubClass(0)
должен быть классом.Достаточно создать внутренний класс InstanceChecker
класс в MySubClass
и поставить __instancecheck__
переопределить их.
Код может быть:
class MySubClass(MySuperClass):
def __new__(cls, name, bases=None, namespace=None, *args, **kwargs):
if bases is not None:
return super().__new__(cls, name, bases, namespace, **kwargs)
return cls.InstanceChecker(name)
class InstanceChecker:
def __init__(self, t):
self.t = t
def __instancecheck__(self, instance):
return isinstance(instance.__class__, MySubClass) and instance.t == self.t
class MyObject(metaclass=MySubClass):
def __init__(self, t):
self.t = t
# Test code:
## Both of these, square brackets work too
assert isinstance(MyObject(0), MySubClass(0))
assert not isinstance(MyObject(0), MySubClass(1))
Кстати, я удалилпереопределение __subclasscheck__
, поскольку t
только в атрибуте instance в MyObject
Кроме того, метакласс может автоматически добавлять суперкласс в параметре bases
,В следующем коде MySuperClass
больше не является суперклассом MySubClass
, а MyObject
:
class MySuperClass():
pass
class MySubClass(type):
def __new__(cls, name, bases=None, namespace=None, *args, **kwargs):
if bases is not None:
return super().__new__(cls, name, bases + (MySuperClass,), namespace, **kwargs)
return cls.InstanceChecker(name)
class InstanceChecker:
def __init__(self, t):
self.t = t
def __instancecheck__(self, instance):
return isinstance(instance.__class__, MySubClass) and instance.t == self.t
class MyObject(metaclass=MySubClass):
def __init__(self, t):
self.t = t
# Test code:
## Both of these, square brackets work too
assert isinstance(MyObject(0), MySubClass(0))
assert not isinstance(MyObject(0), MySubClass(1))
## Ideally
assert isinstance(MyObject(0), MySuperClass)