Checkpoint. Use Finite for the class defining __len__.
This commit is contained in:
parent
7191aa5254
commit
a9354df361
70
pep-3119.txt
70
pep-3119.txt
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue