issubclass(dict, Mapping)
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Wed Dec 22 17:36:14 EST 2010
On Wed, 22 Dec 2010 14:20:51 +0000, kj wrote:
> Here's another example, fresh from today's crop of wonders:
>
> (v. 2.7.0)
>>>> from collections import Mapping
>>>> issubclass(dict, Mapping)
> True
>>>> dict.__bases__
> (<type 'object'>,)
>>>> [issubclass(b, Mapping) for b in dict.__bases__]
> [False]
>
>
> So dict is a subclass of Mapping, even though none of the bases of dict
> is either Mapping or a subclass of Mapping. Great.
Yes. So what?
(1) What *actual* problem does this cause you?
(2) Do you have an example of code that breaks because of this?
(3) Do you understand that since the introduction of ABC (abstract base
classes) in Python 2.6 (I think), isinstance and issubclass checks are
performed cooperatively? The instance or class are asked if they wish to
be known as an instance/subclass of the second argument. Classes can
register themselves as subclasses of (say) Mapping without sharing any
actual code with Mapping.
This is a good thing, and the problem isn't that the abstraction leaks,
as you believe, but the opposite: you're *ignoring* the abstraction and
looking for concrete details that may or may not exist.
I fear that you have fundamentally misunderstood the concept of "leaky
abstraction". It does not mean, as you seem to think, that some concrete
implementation detail differs between two classes (or functions). It
means that some difference in behaviour is exposed, that difference being
irrelevant to the abstraction but nevertheless important in some other
sense. A contrived example:
class MyList(list):
def __len__(self):
import time
time.sleep(3600000)
return list.__len__(self)
MyList can be used anywhere a regular list can be used. Functionally the
two are identical. The abstraction is that MyList is the same as list.
But the leak is that len(MyList()) is *incredibly* slow.
Coming back to Mapping:
Abstraction: issubclass(dict, Mapping)
One possible concrete implementation detail of how issubclass is
implemented:
any(base is Mapping for base in dict.__bases__)
The statement "dict is a subclass of Mapping" is about an abstract
relationship. It's not necessarily a statement about __bases__.
To give an analogy, if you insist on doing DNA testing to determine
whether a boy is a son of a man, you're going to be confused and
distressed every time you find fathers whose sons are genetically
unrelated to them.
--
Steven
More information about the Python-list
mailing list