diff options
author | Andrew M. Kuchling <amk@amk.ca> | 2001-10-26 20:07:03 (GMT) |
---|---|---|
committer | Andrew M. Kuchling <amk@amk.ca> | 2001-10-26 20:07:03 (GMT) |
commit | b83769cb828e97796fecb0336f05b21ae98eacc7 (patch) | |
tree | fc5d9a8470b5a90496f693a0cbf29c9e9c75ac24 /Doc | |
parent | 41cf5e00695d79b0219f5bcce88669e7cf97b572 (diff) | |
download | cpython-b83769cb828e97796fecb0336f05b21ae98eacc7.zip cpython-b83769cb828e97796fecb0336f05b21ae98eacc7.tar.gz cpython-b83769cb828e97796fecb0336f05b21ae98eacc7.tar.bz2 |
Finish off the type/class section; I don't think there's much else
to be covered in an overview article like this.
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/whatsnew/whatsnew22.tex | 198 |
1 files changed, 125 insertions, 73 deletions
diff --git a/Doc/whatsnew/whatsnew22.tex b/Doc/whatsnew/whatsnew22.tex index f68b983..22fa310 100644 --- a/Doc/whatsnew/whatsnew22.tex +++ b/Doc/whatsnew/whatsnew22.tex @@ -1,4 +1,3 @@ - \documentclass{howto} % $Id$ @@ -14,7 +13,7 @@ {\large This document is a draft, and is subject to change until the final version of Python 2.2 is released. Currently it's up to date -for Python 2.2 alpha 4. Please send any comments, bug reports, or +for Python 2.2 beta 1. Please send any comments, bug reports, or questions, no matter how minor, to \email{akuchlin@mems-exchange.org}. } @@ -147,7 +146,8 @@ class C(object): This means that \keyword{class} statements that don't have any base classes are always classic classes in Python 2.2. There's actually a way to make new-style classes without any base classes, by setting the -\member{__metaclass__} variable to XXX. (What do you set it to?) +\member{__metaclass__} variable to XXX (What do you set it to?), but +it's easier to just subclass \keyword{object}. The type objects for the built-in types are available as built-ins, named using a clever trick. Python has always had built-in functions @@ -163,62 +163,23 @@ factories when called. \end{verbatim} To make the set of types complete, new type objects such as -\function{dictionary} and \function{file} have been added. - -Here's a more interesting example. The following class subclasses -Python's dictionary implementation in order to automatically fold all -dictionary keys to lowercase. - -\begin{verbatim} -class LowerCaseDict(dictionary): - def _fold_key (self, key): - if not isinstance(key, str): - raise TypeError, "All keys must be strings" - return key.lower() - - def __getitem__ (self, key): - key = self._fold_key(key) - return dictionary.__getitem__(self, key) - - def __setitem__ (self, key, value): - key = self._fold_key(key) - dictionary.__setitem__(self, key, value) - - def __delitem__ (self, key): - key = self._fold_key(key) - dictionary.__delitem__(self, key, value) -\end{verbatim} - -Trying out this class, it works as you'd expect: +\function{dictionary} and \function{file} have been added. Here's a +more interesting example, adding a \method{lock()} method to file +objects: \begin{verbatim} ->>> d = LowerCaseDict() ->>> d['ABC'] = 1 ->>> d['abc'] -1 -\end{verbatim} - -However, because it's a subclass of Python's dictionary type, -instances of \class{LowerCaseDict} can be used in most places where a -regular dictionary is required. - -\begin{verbatim} ->>> d = LowerCaseDict() ->>> exec 'Name = 1' in d ->>> print d.items() -XXX ->>> exec 'nAmE = name + 1' in d ->>> print d.items() -XXX +class LockableFile(file): + def lock (self, operation, length=0, start=0, whence=0): + import fcntl + return fcntl.lockf(self.fileno(), operation, + length, start, whence) \end{verbatim} -And now you can have Python with case-insensitive variable names! One -of the nice things about Python 2.2 is that it makes Python flexible -enough to solve many other past problems without hacking Python's C -code. If you want a case-insensitive Python environment, using a -case-folding dictionary and writing a case-insensitive tokenizer using -the compiler package (now automatically installed in 2.2) will make it -a straightforward. +The now-obsolete \module{posixfile} module contained a class that +emulated all of a file object's methods and also added a +\method{lock()} method, but this class couldn't be passed to internal +functions that expected a built-in file, something which is possible +with our new \class{LockableFile}. \subsection{Descriptors} @@ -371,14 +332,100 @@ class{A}] after dropping duplicates. Following this rule, referring to \method{D.save()} will return \method{C.save()}, which is the behaviour we're after. This lookup -rule is the same as the one followed by XXX Common Lisp?. +rule is the same as the one followed by Common Lisp. \subsection{Attribute Access} -XXX __getattribute__, __getattr__ +A fair number of sophisticated Python classes define hooks for +attribute access using \method{__getattr__}; most commonly this is +done for convenience, to make code more readable by automatically +mapping an attribute access such as \code{obj.parent} into a method +call such as \code{obj.get_parent()}. Python 2.2 adds some new ways +of controlling attribute access. + +First, \method{__getattr__(\var{attr_name})} is still supported by +new-style classes, and nothing about it has changed. As before, it +will be called when an attempt is made to access \code{obj.foo} and no +attribute named \samp{foo} is found in the instance's dictionary. + +New-style classes also support a new method, +\method{__getattribute__(\var{attr_name})}. The difference between +the two methods is that \method{__getattribute__} is \emph{always} +called whenever any attribute is accessed, while the old +\method{__getattr__} is only called if \samp{foo} isn't found in the +instance's dictionary. + +However, Python 2.2's support for \dfn{properties} will often be a +simpler way to trap attribute references. Writing a +\method{__getattr__} method is complicated because to avoid recursion +you can't use regular attribute accesses inside them, and instead have +to mess around with the contents of \member{__dict__}. +\method{__getattr__} methods also end up being called by Python when +it checks for other methods such as \method{__repr__} or +\method{__coerce__}, and so have to be written with this in mind. +Finally, calling a function on every attribute access results in a +sizable performance loss. + +\class{property} is a new built-in type that packages up three +functions that get, set, or delete an attribute, and a docstring. For +example, if you want to define a \member{size} attribute that's +computed, but also settable, you could write: + +\begin{verbatim} +class C: + def get_size (self): + result = ... computation ... + return result + def set_size (self, size): + ... compute something based on the size + and set internal state appropriately ... + + # Define a property. The 'delete this attribute' + # method is defined as None, so the attribute + # can't be deleted. + size = property(get_size, set_size, + None, + "Storage size of this instance") +\end{verbatim} + +That is certainly clearer and easier to write than a pair of +\method{__getattr__}/\method{__setattr__} methods that check for the +\member{size} attribute and handle it specially, while retrieving all +other attributes from the instance's \member{__dict__}. Accesses to +\member{size} are also the only ones which have to perform the work of +calling a function, letting references to other attributes run at +their usual speed. + +Finally, it's possible to constrain the list of attributes that can be +referenced on an object using the new \member{__slots__} attribute. +Python objects are usually very dynamic; at any time it's possible to +define a new attribute on an instance by just doing +\code{obj.new_attr=1}. This is flexible and convenient, but this +flexibility can also lead to bugs, as when you meant to write +\code{obj.template = 'a'} but make a typo and wrote +\code{obj.templtae} by accident. + +A new-style class can define a class variable named \member{__slots__} +to constrain the list of legal attribute names. An example will make +this clear: + +\begin{verbatim} +>>> class C(object): +... __slots__ = ['template', 'name'] +... +>>> obj = C() +>>> print obj.template +None +>>> obj.template = 'Test' ; obj.name = 'abc' +>>> print obj.template +Test +>>> obj.templtae +Traceback (most recent call last): + File "<stdin>", line 1, in ? +AttributeError: 'C' object has no attribute 'templtae' +\end{verbatim} -XXX properties, slots \subsection{Related Links} @@ -389,23 +436,26 @@ 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 +\url{http://www.python.org/2.2/descrintro.html} is a lengthy tutorial introduction to the descriptor features, written by Guido van Rossum. -% XXX read it and comment on it +If my description has whetted your appetite, go read this tutorial +next, because it goes into much more detail about the new features +while still remaining quite easy to read. 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. +built-in objects. \pep{253} 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. -typeobject.c, others? -% XXX point people at the right files +Finally, there's the ultimate authority: the source code. Most of the +machinery for the type handling is in \file{Objects/typeobject.c}, but +you should only resort to it after all other avenues have been +exhausted (including posting a question to python-list or python-dev.) %====================================================================== @@ -1096,6 +1146,8 @@ embedding the interpreter, or just hacking on the interpreter itself. If you only write Python code, none of the changes described here will affect you very much. +% XXX PyArg_UnpackTuple() + \begin{itemize} \item Profiling and tracing functions can now be implemented in C, @@ -1295,10 +1347,10 @@ to experiment with these modules can uncomment them manually. \section{Acknowledgements} The author would like to thank the following people for offering -suggestions and corrections to various drafts of this article: Fred -Bremmer, Keith Briggs, Andrew Dalke, Fred~L. Drake, Jr., Carel -Fellinger, Mark Hammond, Stephen Hansen, Jack Jansen, Marc-Andr\'e -Lemburg, Fredrik Lundh, Tim Peters, Neil Schemenauer, Guido van -Rossum. +suggestions, corrections and assistance with various drafts of this +article: Fred Bremmer, Keith Briggs, Andrew Dalke, Fred~L. Drake, Jr., +Carel Fellinger, Mark Hammond, Stephen Hansen, Jack Jansen, +Marc-Andr\'e Lemburg, Fredrik Lundh, Tim Peters, Tom Reinhardt, Neil +Schemenauer, Guido van Rossum. \end{document} |