122 lines
4.6 KiB
Plaintext
122 lines
4.6 KiB
Plaintext
PEP: 3119
|
||
Title: Introducing Abstract Base Classes
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Guido van Rossum <guido@python.org>, Talin
|
||
Status: Draft
|
||
Type: Standards Track
|
||
Content-Type: text/x-rst
|
||
Created: 18-Apr-2007
|
||
Post-History: 18-Apr-2007
|
||
|
||
|
||
Abstract
|
||
========
|
||
|
||
This is a proposal to add Abstract Base Class (ABC) support to Python
|
||
3000. It proposes:
|
||
|
||
* An "ABC support framework" which defines a metaclass, a base class,
|
||
a decorator, and some helpers that make it easy to define ABCs.
|
||
This will be added as a new library module named "abc".
|
||
|
||
* Specific ABCs for containers and iterators, to be added to the
|
||
collections module.
|
||
|
||
* Specific ABCs for numbers, to be added to a new module, yet to be
|
||
named.
|
||
|
||
* Guidelines for writing additional ABCs.
|
||
|
||
|
||
Rationale
|
||
=========
|
||
|
||
In the domain of object-oriented programming, the usage patterns for
|
||
interacting with an object can be divided into two basic categories,
|
||
which are 'invocation' and 'inspection'.
|
||
|
||
Invocation means interacting with an object by invoking its methods.
|
||
Usually this is combined with polymorphism, so that invoking a given
|
||
method may run different code depending on the type of an object.
|
||
|
||
Inspection means the ability for external code (outside of the object's
|
||
methods) to examine the type or properties of that object, and make
|
||
decisions on how to treat that object based on that information.
|
||
|
||
Both usage patterns serve the same general end, which is to be able to
|
||
support the processing of diverse and potentially novel objects in a
|
||
uniform way, but at the same time allowing processing decisions to be
|
||
customized for each different type of object.
|
||
|
||
In classical OOP theory, invocation is the preferred usage pattern, and
|
||
inspection is actively discouraged, being considered a relic of an
|
||
earlier, procedural programming style. However, in practice this view is
|
||
simply too dogmatic and inflexible, and leads to a kind of design
|
||
rigidity that is very much at odds with the dynamic nature of a language
|
||
like Python.
|
||
|
||
In particular, there is often a need to process objects in a way that
|
||
wasn't anticipated by the creator of the object class. It is not always
|
||
the best solution to build in to every object methods that satisfy the
|
||
needs of every possible user of that object. Moreover, there are many
|
||
powerful dispatch philosophies that are in direct contrast to the
|
||
classic OOP requirement of behavior being strictly encapsulated within
|
||
an object, examples being rule or pattern-match driven logic.
|
||
|
||
On the the other hand, one of the criticisms of inspection by classic
|
||
OOP theorists is the lack of formalisms and the ad hoc nature of what is
|
||
being inspected. In a language such as Python, in which almost any
|
||
aspect of an object can be reflected and directly accessed by external
|
||
code, there are many different ways to test whether an object conforms
|
||
to a particular protocol or not. For example, if asking 'is this object
|
||
a mutable sequence container?', one can look for a base class of 'list',
|
||
or one can look for a method named '__getitem__'. But note that although
|
||
these tests may seem obvious, neither of them are correct, as one
|
||
generates false negatives, and the other false positives.
|
||
|
||
The generally agreed-upon remedy is to standardize the tests, and group
|
||
them into a formal arrangement. This is most easily done by associating
|
||
with each class a set of standard testable properties, either via the
|
||
inheritance mechanism or some other means. Each test carries with it a
|
||
set of promises: it contains a promise about the general behavior of the
|
||
class, and a promise as to what other class methods will be available.
|
||
|
||
This PEP proposes a particular strategy for organizing these tests known
|
||
as Abstract Base Classes, or ABC. ABCs are simply Python classes that
|
||
are added into an object's inheritance tree to signal certain features
|
||
of that object to an external inspector. Tests are done using
|
||
isinstance(), and the presence of a particular ABC means that the test
|
||
has passed.
|
||
|
||
Like all other things in Python, these promises are in the nature of a
|
||
gentlemen's agreement - which means that the language does not attempt
|
||
to enforce that these promises are kept.
|
||
|
||
|
||
References
|
||
==========
|
||
|
||
.. [1] An Introduction to ABC's, by Talin
|
||
(http://mail.python.org/pipermail/python-3000/2007-April/006614.html)
|
||
|
||
.. [2] Incomplete implementation prototype, by GvR
|
||
(http://svn.python.org/view/sandbox/trunk/abc/)
|
||
|
||
|
||
Copyright
|
||
=========
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
|
||
..
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
sentence-end-double-space: t
|
||
fill-column: 70
|
||
coding: utf-8
|
||
End:
|