__instancecheck__ metaclasses, how do they work: why do I get True when I tuple, why doesn't print run?
Rhodri James
rhodri at kynesim.co.uk
Mon Nov 4 09:10:06 EST 2019
On 04/11/2019 11:30, Veek M wrote:
> 1. Why do I get True whenever i tuple the
> isinstance(f, (Bar, Foo))
> (and why don't the print's run)
I'm not very familiar with metaclasses, but I can answer the second part
of your question.
>
> The docs say that you can feed it a tuple and that the results are OR'd
>
> ----
> The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
> isinstance(x, A) or isinstance(x, B) or ... (etc.).
> -----
> which implies that the metaclasses are called for each class?
>
>
> class MyzMeta(type):
> def __instancecheck__(cls, other):
> print('MyzzzzzzMeta', other)
> return 0
>
>
> class MyMeta(MyzMeta, object):
> def __instancecheck__(cls, other):
> print('MyMeta')
> print(cls, other)
> return 0
>
>
> class Foo(list):
> __metaclass__ = MyzMeta
> pass
>
> class Miaow(object):
> pass
>
> class Bar(Foo, Miaow):
> __metaclass__ = MyMeta
> pass
Aha. You're trying to fix up the metaclass after the fact, which is not
the right way to do it. If you change the class definitions to:
class Foo(list, metaclass=MyzMeta):
pass
class Bar(Foo, Miaow, metaclass=MyMeta):
pass
then you get the prints from MyMeta.__instancecheck__(). The
isinstance() still returns True, though, and I don't know why. Then
again, your definition of MyMeta is really weird.
>
>
> f = Foo()
> b = Bar()
>
> print(isinstance(f, (Bar, Foo)))
--
Rhodri James *-* Kynesim Ltd
More information about the Python-list
mailing list