[Python-checkins] python/dist/src/Doc/ref ref3.tex,1.104,1.105

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Wed, 25 Jun 2003 11:29:39 -0700


Update of /cvsroot/python/python/dist/src/Doc/ref
In directory sc8-pr-cvs1:/tmp/cvs-serv21037

Modified Files:
	ref3.tex 
Log Message:
* Document how descriptors are invoked.
* Fix minor parenthesis matching errors in ref3.tex.



Index: ref3.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v
retrieving revision 1.104
retrieving revision 1.105
diff -C2 -d -r1.104 -r1.105
*** ref3.tex	15 Jun 2003 22:57:44 -0000	1.104
--- ref3.tex	25 Jun 2003 18:29:36 -0000	1.105
***************
*** 482,487 ****
  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{__doc__} is the method's documentation (same as
  \code{im_func.__doc__}); \member{__name__} is the method name (same as
--- 482,487 ----
  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{__doc__} is the method's documentation (same as
  \code{im_func.__doc__}); \member{__name__} is the method name (same as
***************
*** 908,912 ****
  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
  \function{slice()}\bifuncindex{slice} function.
  
--- 908,912 ----
  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
  \function{slice()}\bifuncindex{slice} function.
  
***************
*** 1248,1251 ****
--- 1248,1311 ----
  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.