issubclass(C, Mapping) not behaving as expected
Peter Otten
__peter__ at web.de
Wed May 30 04:38:17 EDT 2012
anntzer.lee at gmail.com wrote:
> from collections import *
> class C(object):
> def __iter__(self): pass
> def __contains__(self, i): pass
> def __len__(self): pass
> def __getitem__(self, i): pass
> issubclass(C, Mapping) => False
> [issubclass(C, cls) for cls in Mapping.__mro__] => [False, True, True,
> [True, True]
> i.e. C does implement Sized, Iterable and Container.
>
> I would have expected that just as issubclass(C, Sized) checks for the
> presence of a "__len__" method, issubclass(C, Mapping) would check for the
> presence of the three methods required by each immediate superclass?
Your expectations are wrong -- as you might have expected ;)
You have two options two get the issubclass() result you want: actually
subclass:
>>> from collections import Mapping as M
>>> class A(M): pass
...
>>> issubclass(A, M)
True
... or register your class:
>>> class B(object): pass
...
>>> issubclass(B, M)
False
>>> M.register(B)
>>> issubclass(B, M)
True
In both cases you are responsible for the correct implementation of the
protocol. Subclassing is normally easier because it fills in missing methods
and complains about required ones on instantiation:
>>> B()
<__main__.B object at 0x7fa34bda3750>
>>> A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class A with abstract methods
__getitem__, __iter__, __len__
More information about the Python-list
mailing list