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
Version: $Revision$
Last-Modified: $Date$
Author: Guido van Rossum <guido@python.org>, Talin
Author: Guido van Rossum <guido@python.org>, Talin <talin@acm.org>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
@ -13,6 +13,8 @@ Post-History: Not yet posted
Abstract
========
**THIS IS A WORK IN PROGRESS! DON'T REVIEW YET!**
This is a proposal to add Abstract Base Class (ABC) support to Python
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.
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
=========
@ -120,12 +127,11 @@ These are:
``@abstractmethod``
A decorator to be used to declare abstract methods. This should
only be used with classes whose metaclass is (or is derived from)
``AbstractClass`` below. A class containing at least one method
declared with this decorator that hasn't been overridden yet
cannot be instantiated. Such a methods may be called from the
overriding method in the subclass (using ``super`` or direct
invocation).
only be used with classes whose class is derived from ``Abstract``
below. A class containing at least one method declared with this
decorator that hasn't been overridden yet cannot be instantiated.
Such a methods may be called from the overriding method in the
subclass (using ``super`` or direct invocation).
``Abstract``
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
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
---------------------------------
@ -199,28 +210,29 @@ These abstract classes represent single methods like ``__iter__`` or
``Iterator``
The base class for classes defining ``__next__``. This derives
from ``Iterable``. Its abstract ``__next__`` method raises
StopIteration. Its ``__iter__`` method returns ``self``, and is
*not* abstract.
``StopIteration``. Its ``__iter__`` method returns ``self``, and
is *not* abstract. (Note: this assumes PEP 3114 is implemented.)
``Lengthy``
``Finite``
The base class for classes defining ``__len__``. Its abstract
``__len__`` method returns 0. (The name is perhaps too cute; but
the only alternatives I've come up with so far are ``Sizeable``,
which suffers from the same affliction, and ``Finite``, which
somehow is associated with numbers instead of sets in my mind.)
``__len__`` method returns 0. Any ``__len__`` method should
return an ``Integer`` (see "Numbers" below) >= 0. If class ``C``
derives from ``Finite`` as well as from ``Iterable``, the
invariant ``sum(1 for x in o) == len(o)`` should hold for any
instance ``o`` of ``C``.
``Container``
The base class for classes defining ``__contains__`. Its abstract
``__contains__`` method returns ``False``. Note: strictly
speaking, there are three variants of this method's semantics.
The first one is for sets and mappings, which is fast: O(1) or
O(log N). The second one is for membership checking on sequences,
which is slow: O(N). The third one is for subsequence checking on
(character or byte) strings, which is also slow: O(N). Would it
make sense to distinguish these? The signature of the third
variant is different, since it takes a sequence (typically of the
same type as the method's target) intead of an element. For now,
I'm using the same type for all three.
The base class for classes defining ``__contains__``. Its
abstract ``__contains__`` method returns ``False``. Note:
strictly speaking, there are three variants of this method's
semantics. The first one is for sets and mappings, which is fast:
O(1) or O(log N). The second one is for membership checking on
sequences, which is slow: O(N). The third one is for subsequence
checking on (character or byte) strings, which is also slow: O(N).
Would it make sense to distinguish these? The signature of the
third variant is different, since it takes a sequence (typically
of the same type as the method's target) intead of an element.
For now, I'm using the same type for all three.
Sets
@ -230,7 +242,7 @@ These abstract classes represent various stages of "set-ness".
``Set``
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
property (though it is not expressed in code) that each element
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,
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.
Similarly, ``__le__`` returns ``False`` immediately if the first
set has more members than the second set. Note that set inclusion
@ -346,7 +358,7 @@ just start with Mapping.
iteration never ends.
``Mapping``
A subclass of ``IterableMapping`` and ``Lengthy``. It defines
A subclass of ``IterableMapping`` and ``Finite``. It defines
concrete methods ``__eq__``, ``keys``, ``items``, ``values``. The
lengh of such an object should equal to the number of elements
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.
``Sequence``
A subclass of ``Iterable``, ``Lengthy``, ``Container``. It
A subclass of ``Iterable``, ``Finite``, ``Container``. It
defines a new abstract method ``__getitem__`` that has a
complicated signature: when called with an integer, it returns an
element of the sequence or raises ``IndexError``; when called with