summaryrefslogtreecommitdiffstats
path: root/Doc/ref
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2003-06-25 18:29:36 (GMT)
committerRaymond Hettinger <python@rcn.com>2003-06-25 18:29:36 (GMT)
commit03ec6d538af8c0f0fc49b300b0d48b98704d8f9b (patch)
treec1cc91aab8e2fbf386b508e1e34687aaac1c4050 /Doc/ref
parent35fd926195320db68b83399eb96d67dc43e5858b (diff)
downloadcpython-03ec6d538af8c0f0fc49b300b0d48b98704d8f9b.zip
cpython-03ec6d538af8c0f0fc49b300b0d48b98704d8f9b.tar.gz
cpython-03ec6d538af8c0f0fc49b300b0d48b98704d8f9b.tar.bz2
* Document how descriptors are invoked.
* Fix minor parenthesis matching errors in ref3.tex.
Diffstat (limited to 'Doc/ref')
-rw-r--r--Doc/ref/ref3.tex66
1 files changed, 63 insertions, 3 deletions
diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex
index a5a5d9f..50d8fa1 100644
--- a/Doc/ref/ref3.tex
+++ b/Doc/ref/ref3.tex
@@ -481,8 +481,8 @@ function).
Special read-only attributes: \member{im_self} is the class instance
object, \member{im_func} is the function object;
-\member{im_class} is the class of \member{im_self} for bound methods,
-or the class that asked for the method for unbound methods);
+\member{im_class} is the class of \member{im_self} for bound methods
+or the class that asked for the method for unbound methods;
\member{__doc__} is the method's documentation (same as
\code{im_func.__doc__}); \member{__name__} is the method name (same as
\code{im_func.__name__}); \member{__module__} is the name of the
@@ -907,7 +907,7 @@ except clause or with a finally clause.
Slice objects are used to represent slices when \emph{extended slice
syntax} is used. This is a slice using two colons, or multiple slices
or ellipses separated by commas, e.g., \code{a[i:j:step]}, \code{a[i:j,
-k:l]}, or \code{a[..., i:j])}. They are also created by the built-in
+k:l]}, or \code{a[..., i:j]}. They are also created by the built-in
\function{slice()}\bifuncindex{slice} function.
Special read-only attributes: \member{start} is the lower bound;
@@ -1249,6 +1249,66 @@ owner class.
\end{methoddesc}
+\subsubsection{Invoking Descriptors \label{descriptor_invocation}}
+
+In general, a descriptor is an object attribute with ``binding behavior'',
+one whose attribute access has been overridden by methods in the descriptor
+protocol: \method{__get__}, \method{__set__}, and \method{__delete__}.
+If any of those methods are defined for an object, it is said to be a
+descriptor.
+
+The default behavior for attribute access is to get, set, or delete the
+attribute from an object's dictionary. For instance, \code{a.x} has a
+lookup chain starting with \code{a.__dict__['x']}, then
+\code{type(a).__dict__['x']}, and continuing
+through the base classes of \code{type(a)} excluding metaclasses.
+
+However, if the looked-up value is an object defining one of the descriptor
+methods, then Python may override the default behavior and invoke the
+descriptor method instead. Where this occurs in the precedence chain depends
+on which descriptor methods were defined and how they were called. Note that
+descriptors are only invoked for new style objects or classes
+(ones that subclass \class{object} or \class{type}).
+
+The starting point for descriptor invocation is a binding, \code{a.x}.
+How the arguments are assembled depends on \code{a}:
+
+\begin{itemize}
+
+ \item[Direct Call] The simplest and least common call is when user code
+ directly invokes a descriptor method: \code{x.__get__(a)}.
+
+ \item[Instance Binding] If binding to a new-style object instance,
+ \code{a.x} is transformed into the call:
+ \code{type(a).__dict__['x'].__get__(a, type(a))}.
+
+ \item[Class Binding] If binding to a new-style class, \code{A.x}
+ is transformed into the call: \code{A.__dict__['x'].__get__(None, A)}.
+
+ \item[Super Binding] If \code{a} is an instance of \class{super},
+ then the binding \code{super(B, obj).m()} searches
+ \code{obj.__class__.__mro__} for the base class \code{A} immediately
+ preceding \code{B} and then invokes the descriptor with the call:
+ \code{A.__dict__['m'].__get__(obj, A)}.
+
+\end{itemize}
+
+For instance bindings, the precedence of descriptor invocation depends
+on the which descriptor methods are defined. Data descriptors define
+both \method{__get__} and \method{__set__}. Non-data descriptors have
+just the \method{__get__} method. Data descriptors always override
+a redefinition in an instance dictionary. In contrast, non-data
+descriptors can be overridden by instances.
+
+Python methods (including \function{staticmethod} and \function{classmethod})
+are implemented as non-data descriptors. Accordingly, instances can
+redefine and override methods. This allows individual instances to acquire
+behaviors that differ from other instances of the same class.
+
+The \function{property} function is implemented as a data descriptor.
+Accordingly, instances cannot override the behavior a property.
+
+
\subsection{Emulating callable objects\label{callable-types}}
\begin{methoddesc}[object]{__call__}{self\optional{, args...}}