From: A.M. K. <aku...@us...> - 2001-10-22 02:03:47
|
Update of /cvsroot/py-howto/pyhowto In directory usw-pr-cvs1:/tmp/cvs-serv1828 Modified Files: python-22.tex Log Message: Partly fill out the PEP 252 section Index: python-22.tex =================================================================== RCS file: /cvsroot/py-howto/pyhowto/python-22.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** python-22.tex 2001/10/22 02:00:11 1.32 --- python-22.tex 2001/10/22 02:03:40 1.33 *************** *** 53,67 **** \section{PEP 252: Type and Class Changes} ! XXX I need to read and digest the relevant PEPs. ! \begin{seealso} ! \seepep{252}{Making Types Look More Like Classes}{Written and implemented ! by Guido van Rossum.} ! \seeurl{http://www.python.org/2.2/descrintro.html}{A tutorial ! on the type/class changes in 2.2.} ! \end{seealso} --- 53,269 ---- \section{PEP 252: Type and Class Changes} ! The largest and most far-reaching changes in Python 2.2 are to ! Python's model of objects and classes. The changes should be backward ! compatible, so it's likely that your code will continue to run ! unchanged, but the changes provide some amazing new capabilities. ! Before beginning this, the longest and most complicated section of ! this article, I'll provide an overview of the changes and offer some ! comments. ! ! A long time ago I wrote a Web page ! (\url{http://www.amk.ca/python/writing/warts.html}) listing flaws in ! Python's design. One of the most significant flaws was that it's ! impossible to subclass Python types implemented in C. In particular, ! it's not possible to subclass built-in types, so you can't just ! subclass, say, lists in order to add a single useful method to them. ! The \module{UserList} module provides a class that supports all of the ! methods of lists and that can be subclassed further, but there's lots ! of C code that expects a regular Python list and won't accept a ! \class{UserList} instance. ! Python 2.2 fixes this, and in the process adds some exciting new ! capabilities. A brief summary: ! \begin{itemize} ! \item You can subclass built-in types such as lists and even integers, ! and your subclasses should work in every place that requires the ! original type. ! ! \item It's now possible to define static and class methods, in addition ! to the instance methods available in previous versions of Python. ! ! \item It's also possible to automatically call methods on accessing or ! setting an instance attribute by using a new mechanism called ! \dfn{properties}. Many uses of \method{__getattr__} can be rewritten ! to use properties instead, making the resulting code simpler and ! faster. As a small side benefit, attributes can now have docstrings, ! too. ! ! \item The list of legal attributes for an instance can be limited to a ! particular set using \dfn{slots}, making it possible to safeguard ! against typos and perhaps make more optimizations possible in future ! versions of Python. ! \end{itemize} ! ! Some users have voiced concern about all these changes. Sure, they ! say, the new features are neat and lend themselves to all sorts of ! tricks that weren't possible in previous versions of Python, but ! they also make the language more complicated. Some people have said ! that they've always recommended Python for its simplicity, and feel ! that its simplicity is being lost. ! ! Personally, I think there's no need to worry. Many of the new ! features are quite esoteric, and you can write a lot of Python code ! without ever needed to be aware of them. Writing a simple class is no ! more difficult than it ever was, so you don't need to bother learning ! or teaching them unless they're actually needed. Some very ! complicated tasks that were previously only possible from C will now ! be possible in pure Python, and to my mind that's all for the better. ! ! I'm not going to attempt to cover every single corner case and small ! change that were required to make the new features work. Instead this ! section will paint only the broad strokes. See section~\cite{sect-rellinks}, ! ``Related Links'', for further sources of information about Python 2.2's new ! object model. ! ! ! \subsection{Old and New Classes} ! ! First, you should know that Python 2.2 really has two kinds of ! classes: classic or old-style classes, and new-style classes. The ! old-style class model is exactly the same as the class model in ! earlier versions of Python. All the new features described in this ! section apply only to new-style classes. This divergence isn't ! intended to last forever; eventually old-style classes will be ! dropped, possibly in Python 3.0. ! ! So how do you define a new-style class? XXX ! Subclass object -- subclass a built-in type. ! ! ! \subsection{Descriptors} ! ! In previous versions of Python, there was no consistent way to ! discover what attributes and methods were supported by an object. ! There were some informal conventions, such as defining ! \member{__members__} and \member{__methods__} attributes that were ! lists of names, but often the author of an extension type or a class ! wouldn't bother to define them. You could fall back on inspecting the ! \member{__dict__} of an object, but when class inheritance or an ! arbitrary \method{__getattr__} hook were in use this could still be ! inaccurate. ! ! The one big idea underlying the new class model is that an API for ! describing the attributes of an object using \dfn{descriptors} has ! been formalized. Descriptors specify the value of an attribute, ! stating whether it's a method or a field. With the descriptor API, ! static methods and class methods become possible, as well as more ! exotic constructs. ! ! Attribute descriptors are objects that live inside class objects, and ! have a few attributes of their own: ! ! \begin{itemize} ! ! \item \member{__name__} is the attribute's name. ! ! \item \member{__doc__} is the attribute's docstring. ! ! \item \method{__get__(\var{object})} is a method that retrieves the attribute value from \var{object}. ! ! \item \method{__get__(\var{object}, \var{value})} sets the attribute ! on \var{object} to \var{value}. ! ! \end{itemize} ! ! For example, when you write \code{obj.x}, the steps that Python ! actually performs are: ! ! \begin{verbatim} ! descriptor = obj.__class__.x ! descriptor.get(obj) ! \end{verbatim} ! ! For methods, \method{descriptor.get} returns a temporary object that's ! callable, and wraps up the instance and the method to be called on it. ! This is also why static methods and class methods are now possible; ! they have descriptors that wrap up just the method, or the method and ! the class. As a brief explanation of these new kinds of methods, ! static methods aren't passed the instance, and therefore resemble ! regular functions. Class methods are passed the class of the object, ! but not the object itself. Static and class methods is defined like ! this: ! ! \begin{verbatim} ! class C: ! def f(arg1, arg2): ! ... ! f = staticmethod(f) ! ! def g(cls, arg1, arg2): ! ... ! g = classmethod(g) ! \end{verbatim} ! ! The \function{staticmethod()} function takes the function ! \function{f}, and returns it wrapped up in a descriptor so it can be ! stored in the class object. You might expect there to be special ! syntax for creating such methods (\code{def static f()}, ! \code{defstatic f()}, or something like that) but no such syntax has ! been defined yet; that's been left for future versions. ! ! More new features, such as slots and properties, are also implemented ! as new kinds of descriptors, and it's not difficult to write a ! descriptor class that does something novel. For example, it would be ! possible to write a descriptor class that made it possible to write ! Eiffel-style preconditions and postconditions for a method. A class ! that used this feature might be defined like this: ! ! \begin{verbatim} ! from eiffel import eiffelmethod ! ! class C: ! def f(self, arg1, arg2): ! # The actual function ! def pre_f(self): ! # Check preconditions ! def post_f(self): ! # Check postconditions ! ! f = eiffelmethod(f, pre_f, post_f) ! \end{verbatim} ! ! Note that a person using the new \function{eiffelmethod()} doesn't ! have to understand anything about descriptors. This is why I think ! the new features don't increase the basic complexity of the language. ! There will be a few wizards who need to know about it in order to ! write \function{eiffelmethod()} or the ZODB or whatever, but most ! users will just write code on top of the resulting libraries and ! ignore the implementation details. ! ! \subsection{Inheritance Lookup: The Diamond Rule} ! ! XXX ! ! \subsection{Attribute Access} ! ! XXX __getattribute__, __getattr__ ! ! \subsection{Related Links} ! \ref{sect-rellinks} ! ! This section has just been a quick overview of the new features, ! giving enough of an explanation to start you programming, but many ! details have been simplified or ignored. Where should you go to get a ! more complete picture? ! ! \url{http://www.python.org/2.2/descrintro.html} is a tutorial ! introduction to the descriptor features, written by Guido van Rossum. ! % XXX read it and comment on it ! ! Next, there are two relevant PEPs, \pep{252} and \pep{253}. \pep{252} ! is titled "Making Types Look More Like Classes", and covers the ! descriptor API. \pep{253} is titled "Subtyping Built-in Types", and ! describes the changes to type objects that make it possible to subtype ! built-in objects. This is the more complicated PEP of the two, and at ! a few points the necessary explanations of types and meta-types may ! cause your head to explode. Both PEPs were written and implemented by ! Guido van Rossum, with substantial assistance from the rest of the ! Zope Corp. team. ! ! Finally, there's the ultimate authority: the source code. ! % XXX point people at the right files *************** *** 486,490 **** please offer comments on the PEP and on your experiences with the 2.2 beta releases. ! % XXX update previous line once 2.2 reaches beta. Another change is much simpler to explain. Since their introduction, --- 688,692 ---- please offer comments on the PEP and on your experiences with the 2.2 beta releases. ! % XXX update previous line once 2.2 reaches beta or final. Another change is much simpler to explain. Since their introduction, *************** *** 826,830 **** \item The code for the MacOS port for Python, maintained by Jack Jansen, is now kept in the main Python CVS tree, and many changes ! have been made to support MacOS X. The most significant change is the ability to build Python as a --- 1028,1032 ---- \item The code for the MacOS port for Python, maintained by Jack Jansen, is now kept in the main Python CVS tree, and many changes ! have been made to support MacOS~X. The most significant change is the ability to build Python as a *************** *** 832,836 **** option to the configure script when compiling Python. According to Jack Jansen, ``This installs a self-contained Python installation plus ! the OSX framework "glue" into \file{/Library/Frameworks/Python.framework} (or another location of choice). For now there is little immediate added benefit to this --- 1034,1038 ---- option to the configure script when compiling Python. According to Jack Jansen, ``This installs a self-contained Python installation plus ! the OS~X framework "glue" into \file{/Library/Frameworks/Python.framework} (or another location of choice). For now there is little immediate added benefit to this *************** *** 841,846 **** Most of the MacPython toolbox modules, which interface to MacOS APIs ! such as windowing, QuickTime, scripting, etc. have been ported to OS ! X, but they've been left commented out in \filename{setup.py}. People who want to experiment with these modules can uncomment them manually. --- 1043,1048 ---- Most of the MacPython toolbox modules, which interface to MacOS APIs ! such as windowing, QuickTime, scripting, etc. have been ported to OS~X, ! but they've been left commented out in \filename{setup.py}. People who want to experiment with these modules can uncomment them manually. |