The Python 2 data model talks about __slots__ :
- When inheriting from a class without
__slots__ attribute of this class will always be available, so defining __slots__ in a subclass is pointless.
And here is what happens here. In Python 2, abstract base classes in the collections module did not have __slots__ at all:
>>> from collections import Sequence >>> Sequence.__slots__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'Sequence' has no attribute '__slots__'
This was reported in issue 11333 in the problem tracking log on CPython and fixed in Python 3.3.
In Python 3.3+, the Sequence base class now has __slots__ for an empty tuple:
>>> from collections import Sequence >>> Sequence.__slots__ ()
So in Python 2 you cannot inherit from the base class collections and at the same time have storage with memory with __slots__ .
Note that although the documentation for collections abstract base classes claims that
These ABCs allow us to define classes or instances if they provide specific functionality, for example:
size = None if isinstance(myvar, collections.Sized): size = len(myvar)
This does not apply to Sequence ; simply executing all the methods required by Sequence does not make instances of your class to validate isinstance .
The reason for this is that the Sequence class does not have __subclasshook__ ; and in its absence, the parent class __subclasshook__ ; in this case, Sized.__subclasshook__ ; and returns NotImplemented if the NotImplemented class was not exactly Sized .
On the other hand, it was impossible to distinguish between display type and sequence type by magic methods, since both of them can have exactly the same magic methods - collections.OrderedDict have all the magic methods of a Sequence , including the __reversed__ method, but this is not a sequence.
However, you still don't need to inherit from Sequence to make isinstance(Point, Sequence) return True . In the following example, Point is the same as derived from object instead of Sequence in Python 2:
>>> pt = Point(12, 42) >>> pt.z = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Point' object has no attribute 'z' >>> isinstance(pt, Sequence) False >>> Sequence.register(pt) >>> isinstance(pt, Sequence) True
You can register any class as a subclass of an abstract base class for the purpose of checking isinstance ; and additional mixing methods, you really only need to implement count and index ; functionality for others will be populated with Python runtime.