Checkpoint. Use Finite for the class defining __len__.

This commit is contained in:
Guido van Rossum 2007-04-19 17:58:47 +00:00
parent 7191aa5254
commit a9354df361
1 changed files with 41 additions and 29 deletions

View File

@ -2,7 +2,7 @@ PEP: 3119
Title: Introducing Abstract Base Classes Title: Introducing Abstract Base Classes
Version: $Revision$ Version: $Revision$
Last-Modified: $Date$ Last-Modified: $Date$
Author: Guido van Rossum <guido@python.org>, Talin Author: Guido van Rossum <guido@python.org>, Talin <talin@acm.org>
Status: Draft Status: Draft
Type: Standards Track Type: Standards Track
Content-Type: text/x-rst Content-Type: text/x-rst
@ -13,6 +13,8 @@ Post-History: Not yet posted
Abstract Abstract
======== ========
**THIS IS A WORK IN PROGRESS! DON'T REVIEW YET!**
This is a proposal to add Abstract Base Class (ABC) support to Python This is a proposal to add Abstract Base Class (ABC) support to Python
3000. It proposes: 3000. It proposes:
@ -28,6 +30,11 @@ This is a proposal to add Abstract Base Class (ABC) support to Python
* Guidelines for writing additional ABCs. * Guidelines for writing additional ABCs.
Much of the thinking that went into the proposal is not about the
specific mechanism of ABCs, as contrasted with Interfaces or Generic
Functions (GFs), but about clarifying philosophical issues like "what
makes a set", "what makes a mapping" and "what makes a sequence".
Rationale Rationale
========= =========
@ -120,12 +127,11 @@ These are:
``@abstractmethod`` ``@abstractmethod``
A decorator to be used to declare abstract methods. This should A decorator to be used to declare abstract methods. This should
only be used with classes whose metaclass is (or is derived from) only be used with classes whose class is derived from ``Abstract``
``AbstractClass`` below. A class containing at least one method below. A class containing at least one method declared with this
declared with this decorator that hasn't been overridden yet decorator that hasn't been overridden yet cannot be instantiated.
cannot be instantiated. Such a methods may be called from the Such a methods may be called from the overriding method in the
overriding method in the subclass (using ``super`` or direct subclass (using ``super`` or direct invocation).
invocation).
``Abstract`` ``Abstract``
A class implementing the constraint that it or its subclasses A class implementing the constraint that it or its subclasses
@ -152,6 +158,11 @@ a class attribute named ``__abstractmethods__``. Then the
``Abstract.__new__()`` method would raise an exception if any abstract ``Abstract.__new__()`` method would raise an exception if any abstract
methods exist on the class being instantiated. For details see [2]_. methods exist on the class being instantiated. For details see [2]_.
**Open issue:** perhaps ``abstractmethod`` and
``AbstractInstantiationError`` should become built-ins, ``Abstract``'s
functionality should be subsumed by ``object``, and
``AbstractClass``'s functionality should be merged into ``type``.
ABCs for Containers and Iterators ABCs for Containers and Iterators
--------------------------------- ---------------------------------
@ -199,28 +210,29 @@ These abstract classes represent single methods like ``__iter__`` or
``Iterator`` ``Iterator``
The base class for classes defining ``__next__``. This derives The base class for classes defining ``__next__``. This derives
from ``Iterable``. Its abstract ``__next__`` method raises from ``Iterable``. Its abstract ``__next__`` method raises
StopIteration. Its ``__iter__`` method returns ``self``, and is ``StopIteration``. Its ``__iter__`` method returns ``self``, and
*not* abstract. is *not* abstract. (Note: this assumes PEP 3114 is implemented.)
``Lengthy`` ``Finite``
The base class for classes defining ``__len__``. Its abstract The base class for classes defining ``__len__``. Its abstract
``__len__`` method returns 0. (The name is perhaps too cute; but ``__len__`` method returns 0. Any ``__len__`` method should
the only alternatives I've come up with so far are ``Sizeable``, return an ``Integer`` (see "Numbers" below) >= 0. If class ``C``
which suffers from the same affliction, and ``Finite``, which derives from ``Finite`` as well as from ``Iterable``, the
somehow is associated with numbers instead of sets in my mind.) invariant ``sum(1 for x in o) == len(o)`` should hold for any
instance ``o`` of ``C``.
``Container`` ``Container``
The base class for classes defining ``__contains__`. Its abstract The base class for classes defining ``__contains__``. Its
``__contains__`` method returns ``False``. Note: strictly abstract ``__contains__`` method returns ``False``. Note:
speaking, there are three variants of this method's semantics. strictly speaking, there are three variants of this method's
The first one is for sets and mappings, which is fast: O(1) or semantics. The first one is for sets and mappings, which is fast:
O(log N). The second one is for membership checking on sequences, O(1) or O(log N). The second one is for membership checking on
which is slow: O(N). The third one is for subsequence checking on sequences, which is slow: O(N). The third one is for subsequence
(character or byte) strings, which is also slow: O(N). Would it checking on (character or byte) strings, which is also slow: O(N).
make sense to distinguish these? The signature of the third Would it make sense to distinguish these? The signature of the
variant is different, since it takes a sequence (typically of the third variant is different, since it takes a sequence (typically
same type as the method's target) intead of an element. For now, of the same type as the method's target) intead of an element.
I'm using the same type for all three. For now, I'm using the same type for all three.
Sets Sets
@ -230,7 +242,7 @@ These abstract classes represent various stages of "set-ness".
``Set`` ``Set``
This is a finite, iterable container, i.e. a subclass of This is a finite, iterable container, i.e. a subclass of
``Lengthy``, ``Iterable`` and ``Container``. Not every subset of ``Finite``, ``Iterable`` and ``Container``. Not every subset of
those three classes is a set though! Sets have the additional those three classes is a set though! Sets have the additional
property (though it is not expressed in code) that each element property (though it is not expressed in code) that each element
occurs only once (as can be determined by iteration), and in occurs only once (as can be determined by iteration), and in
@ -239,7 +251,7 @@ These abstract classes represent various stages of "set-ness".
Sets with different implementations can be compared safely, Sets with different implementations can be compared safely,
efficiently and correctly. Because ``Set`` derives from efficiently and correctly. Because ``Set`` derives from
``Lengthy``, ``__eq__`` takes a shortcut and returns ``False`` ``Finite``, ``__eq__`` takes a shortcut and returns ``False``
immediately if two sets of unequal length are compared. immediately if two sets of unequal length are compared.
Similarly, ``__le__`` returns ``False`` immediately if the first Similarly, ``__le__`` returns ``False`` immediately if the first
set has more members than the second set. Note that set inclusion set has more members than the second set. Note that set inclusion
@ -346,7 +358,7 @@ just start with Mapping.
iteration never ends. iteration never ends.
``Mapping`` ``Mapping``
A subclass of ``IterableMapping`` and ``Lengthy``. It defines A subclass of ``IterableMapping`` and ``Finite``. It defines
concrete methods ``__eq__``, ``keys``, ``items``, ``values``. The concrete methods ``__eq__``, ``keys``, ``items``, ``values``. The
lengh of such an object should equal to the number of elements lengh of such an object should equal to the number of elements
returned by iterating over the object until the end of the returned by iterating over the object until the end of the
@ -376,7 +388,7 @@ Sequences
These abstract classes represent various stages of sequence-ness. These abstract classes represent various stages of sequence-ness.
``Sequence`` ``Sequence``
A subclass of ``Iterable``, ``Lengthy``, ``Container``. It A subclass of ``Iterable``, ``Finite``, ``Container``. It
defines a new abstract method ``__getitem__`` that has a defines a new abstract method ``__getitem__`` that has a
complicated signature: when called with an integer, it returns an complicated signature: when called with an integer, it returns an
element of the sequence or raises ``IndexError``; when called with element of the sequence or raises ``IndexError``; when called with