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
|
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
|
||||||
|
|
Loading…
Reference in New Issue