Add the first bits of PEP 252, Making Types Look More Like Classes.
This commit is contained in:
parent
b5b9314dea
commit
3fbd95d184
|
@ -51,6 +51,7 @@ Index by Category
|
||||||
S 246 pep-0246.txt Object Adaptation Evans
|
S 246 pep-0246.txt Object Adaptation Evans
|
||||||
S 250 pep-0250.txt Using site-packages on All Platforms Moore
|
S 250 pep-0250.txt Using site-packages on All Platforms Moore
|
||||||
I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw
|
I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw
|
||||||
|
S 252 pep-0252.txt Making Types Look More Like Classes van Rossum
|
||||||
|
|
||||||
Py-in-the-sky PEPs (not ready; may become active yet)
|
Py-in-the-sky PEPs (not ready; may become active yet)
|
||||||
|
|
||||||
|
@ -170,6 +171,7 @@ Numerical Index
|
||||||
I 249 pep-0249.txt Python Database API Specification v2.0 Lemburg
|
I 249 pep-0249.txt Python Database API Specification v2.0 Lemburg
|
||||||
S 250 pep-0250.txt Using site-packages on All Platforms Moore
|
S 250 pep-0250.txt Using site-packages on All Platforms Moore
|
||||||
I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw
|
I 251 pep-0251.txt Python 2.2 Release Schedule Warsaw
|
||||||
|
S 252 pep-0252.txt Making Types Look More Like Classes van Rossum
|
||||||
|
|
||||||
|
|
||||||
Key
|
Key
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
PEP: 252
|
||||||
|
Title: Making Types Look More Like Classes
|
||||||
|
Version: $Revision$
|
||||||
|
Author: guido@python.org (Jeremy Hylton)
|
||||||
|
Status: Draft
|
||||||
|
Type: Standards Track
|
||||||
|
Python-Version: 2.2
|
||||||
|
Created: 19-Apr-2001
|
||||||
|
Post-History:
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
|
||||||
|
This PEP proposes changes to the introspection API for types that
|
||||||
|
makes them look more like classes. For example, type(x) will be
|
||||||
|
equivalent to x.__class__ for most built-in types. When C is
|
||||||
|
x.__class__, x.meth(a) will be equivalent to C.meth(x, a), and
|
||||||
|
C.__dict__ contains descriptors for x's methods and other
|
||||||
|
attributes.
|
||||||
|
|
||||||
|
The PEP also introduces a new approach to specifying attributes,
|
||||||
|
using attribute descriptors, or descriptors for short.
|
||||||
|
Descriptors unify and generalize several different common
|
||||||
|
mechanisms used for describing attributes: a descriptor can be an
|
||||||
|
unbound method, a typed field in the object structure, or a
|
||||||
|
generalized attribute represented by getter and setter functions
|
||||||
|
(or just a getter function, for read-only attributes).
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
|
||||||
|
One of Python's oldest language warts is the difference between
|
||||||
|
classes and types. For example, you can't directly subclass the
|
||||||
|
dictionary type, and the introspection interface for finding out
|
||||||
|
what methods and instance variables an object has is different for
|
||||||
|
types and for classes.
|
||||||
|
|
||||||
|
Healing the class/type split is a big effort, because it affects
|
||||||
|
many aspects of how Python is implemented. This PEP concerns
|
||||||
|
itself with making the introspection API for types look the same
|
||||||
|
as that for classes. Other PEPs will propose making classes look
|
||||||
|
more like types, and subclassing from built-in types; these topics
|
||||||
|
are not on the table for this PEP.
|
||||||
|
|
||||||
|
Introspection APIs
|
||||||
|
|
||||||
|
Introspection concerns itself with finding out what attributes an
|
||||||
|
object has. Python's very general getattr/setattr API makes it
|
||||||
|
impossible to guarantee that there always is a way to get a list
|
||||||
|
of all attributes supported by a specific object, but in practice
|
||||||
|
two conventions have appeared that together work for almost all
|
||||||
|
objects.
|
||||||
|
|
||||||
|
The first API is used primarily for class instances; it is also
|
||||||
|
used by Digital Creations's ExtensionClasses. It assumes that all
|
||||||
|
data attributes of an object x are stored in the dictionary
|
||||||
|
x.__dict__, and that all methods and class variables can be found
|
||||||
|
by inspection of x's class, written as x.__class__. Classes have
|
||||||
|
a __dict__ attribute, which yields a dictionary containing methods
|
||||||
|
and class variables defined by the class itself, and a __bases__
|
||||||
|
attribute, which is a tuple of base classes that must be inspected
|
||||||
|
recursively. Some assumption here are:
|
||||||
|
|
||||||
|
- attributes defined in the instance dict override attributes
|
||||||
|
defined by the object's class;
|
||||||
|
|
||||||
|
- attributes defined in a derived class override attributes
|
||||||
|
defined in a base class;
|
||||||
|
|
||||||
|
- attributes in an earlier base class (meaning occurring earlier
|
||||||
|
in __bases__) override attributes in a later base class.
|
||||||
|
|
||||||
|
(The last two rules together are often summarized as the
|
||||||
|
left-to-right, depth-first rule for attribute search.)
|
||||||
|
|
||||||
|
The second introspection API is supported in one form or another
|
||||||
|
by most built-in objects. It uses two special attributes,
|
||||||
|
__members__ and __methods__. The __members__ attribute, if
|
||||||
|
present, is a list of method names supported by the object. The
|
||||||
|
__methods__ attribute, if present, is a list of data attribute
|
||||||
|
names supported by the object.
|
||||||
|
|
||||||
|
This API is sometimes combined by a __dict__ that works the same
|
||||||
|
was as for instances (e.g., for function objects in Python 2.1,
|
||||||
|
f.__dict__ contains f's dynamic attributes, while f.__members__
|
||||||
|
lists the names of f's statically defined attributes).
|
||||||
|
|
||||||
|
Some caution must be exercised: some objects don't list theire
|
||||||
|
"intrinsic" attributes (e.g. __dict__ and __doc__) in __members__,
|
||||||
|
while others do; sometimes attribute names that occur both in
|
||||||
|
__members__ or __methods__ and as keys in __dict__, in which case
|
||||||
|
it's anybody's guess whether the value found in __dict__ is used
|
||||||
|
or not.
|
||||||
|
|
||||||
|
This second introspection API has never been carefully specified.
|
||||||
|
It is part of folklore, and most 3rd party extensions support it
|
||||||
|
because they follow examples that support it. Also, any type that
|
||||||
|
uses Py_FindMethod() and/or PyMember_Get() in its tp_getattr
|
||||||
|
handler supports it, because these two functions special-case the
|
||||||
|
attribute names __methods__ and __members__, respectively.
|
||||||
|
|
||||||
|
Digital Creations's ExtensionClasses ignore the second
|
||||||
|
introspection API, and instead emulate the class instance
|
||||||
|
introspection API, which is more powerful. In this PEP, I propose
|
||||||
|
to phase out the second API in favor of supporting the class
|
||||||
|
instance introspection API for all types.
|
||||||
|
|
||||||
|
One argument in favor of the class instance introspection API is
|
||||||
|
that it doesn't require you to create an instance in order to find
|
||||||
|
out which attributes a type supports; this in turn is useful for
|
||||||
|
documentation processors. For example, the socket module exports
|
||||||
|
the SocketType object, but this currently doesn't tell us what
|
||||||
|
methods are defined on socket objects.
|
||||||
|
|
||||||
|
Specification
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Discussion
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Examples
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Backwards compatibility
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Compatibility of C API
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Warnings and Errors
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
References
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
|
||||||
|
Local Variables:
|
||||||
|
mode: indented-text
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
Loading…
Reference in New Issue