|
From: A.M. K. <aku...@us...> - 2001-02-14 02:43:40
|
Update of /cvsroot/py-howto/pyhowto
In directory usw-pr-cvs1:/tmp/cvs-serv23762
Modified Files:
python-21.tex
Log Message:
Finished the section on weak references
Mentioned doctest, difflib, sys._getframe(), and the change to use
PyImport_ImportModule() everywhere in C code
No more XXX!
Index: python-21.tex
===================================================================
RCS file: /cvsroot/py-howto/pyhowto/python-21.tex,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -r1.11 -r1.12
*** python-21.tex 2001/02/11 16:55:39 1.11
--- python-21.tex 2001/02/14 02:44:18 1.12
***************
*** 1,6 ****
\documentclass{howto}
- % XXX difflib.py, doctest.py added
-
% $Id$
--- 1,4 ----
***************
*** 95,109 ****
This seems rather unlikely though, since such code would have been
pretty confusing to read in the first place.
! One side effect of the change is that the statement from \code{from
! \var{module} import *} has been made illegal inside a function scope.
! The Python reference manual has said all along that \code{from
! \var{module} import *} is only legal at the top level of a module, but
! the CPython interpreter has never enforced this before; it will be
! enforced in 2.1, though it's not yet clear if it will be a syntax
! error or just a warning. In the alpha 2 release, it triggers a
! \exception{SyntaxError} exception, but this check might be made more
! lenient in following releases.
! % XXX update the previous sentence for 2.1final
\begin{seealso}
--- 93,130 ----
This seems rather unlikely though, since such code would have been
pretty confusing to read in the first place.
+
+ One side effect of the change is that the \code{from \var{module}
+ import *} and \keyword{exec} statements have been made illegal inside
+ a function scope under certain conditions. The Python reference
+ manual has said all along that \code{from \var{module} import *} is
+ only legal at the top level of a module, but the CPython interpreter
+ has never enforced this before. As part of the implementation of
+ nested scopes, the compiler which turns Python source into bytecodes
+ has to generate different code to access variables in a containing
+ scope. \code{from \var{module} import *} and \keyword{exec} make it
+ impossible for the compiler to figure this out, because they add names
+ to the local namespace that are unknowable at compile time.
+ Therefore, if a function contains function definitions or
+ \keyword{lambda} expressions with free variables, the compiler will
+ flag this by raising a \exception{SyntaxError} exception.
+
+ To make the preceding explanation a bit clearer, here's an example:
+
+ \begin{verbatim}
+ x = 1
+ def f():
+ # The next line is a syntax error
+ exec 'x=2'
+ def g():
+ return x
+ \end{verbatim}
! Line 4 containing the \keyword{exec} statement is a syntax error,
! since \keyword{exec} would define a new local variable named \samp{x}
! whose value should be accessed by \function{g()}.
!
! This shouldn't be much of a limitation, since \keyword{exec} is rarely
! used in most Python code (and when it is used, it's often a sign of a
! poor design anyway).
\begin{seealso}
***************
*** 351,370 ****
%======================================================================
! \section{Weak References}
! Weak references are a minor but useful new data type in the Python
! programmer's toolbox. Storing a reference to an object (say, in a
! dictionary or a list) has the side effect of keeping that object alive
! forever. There are a few specific cases where this behaviour is
! undesirable, object caches being the most common one, and another
! being circular references in data structures such as trees.
!
! For example, a tree might be implemented as a set of \class{Node}
! instances where each instances contains a list of its children. If
! you need to be able to determine the parent of a given \class{Node},
! an obvious solution would be to have each instance have a reference to
! its parent. This creates lots of circular references.
! XXX finish the rest of this section
\begin{seealso}
--- 372,457 ----
%======================================================================
! \section{PEP 205: Weak References}
!
! Weak references, available through the \module{weakref} module, are a
! minor but useful new data type in the Python programmer's toolbox.
!
! Storing a reference to an object (say, in a dictionary or a list) has
! the side effect of keeping that object alive forever. There are a few
! specific cases where this behaviour is undesirable, object caches
! being the most common one, and another being circular references in
! data structures such as trees.
!
! For example, consider a memoizing function that caches the results of
! another function \function{f(\var{x})} by storing the function's
! argument and its result in a dictionary:
!
! \begin{verbatim}
! _cache = {}
! def memoize(x):
! if _cache.has_key(x):
! return _cache[x]
!
! retval = f(x)
!
! # Cache the returned object
! _cache[x] = retval
!
! return retval
! \end{verbatim}
!
! This version works for simple things such as integers, but it has a
! side effect; the \code{_cache} dictionary holds a reference to the
! return values, so they'll never be deallocated until the Python
! process exits and cleans up This isn't very noticeable for integers,
! but if \function{f()} returns an object, or a data structure that
! takes up a lot of memory, this can be a problem.
!
! Weak references provide a way to implement a cache that won't keep
! objects alive beyond their time. If an object is only accessible
! through weak references, the object will be deallocated and the weak
! references will now indicate that the object it referred to no longer
! exists. A weak reference to an object \var{obj} is created by calling
! \code{wr = weakref.ref(\var{obj})}. The object being referred to is
! returned by calling the weak reference as if it were a function:
! \code{wr()}. It will return the referenced object, or \code{None} if
! the object no longer exists.
!
! This makes it possible to write a \function{memoize()} function whose
! cache doesn't keep objects alive, by storing weak references in the
! cache.
!
! \begin{verbatim}
! _cache = {}
! def memoize(x):
! if _cache.has_key(x):
! obj = _cache[x]()
! # If weak reference object still exists,
! # return it
! if obj is not None: return obj
!
! retval = f(x)
!
! # Cache a weak reference
! _cache[x] = weakref.ref(retval)
!
! return retval
! \end{verbatim}
! The \module{weakref} module also allows creating proxy objects which
! behave like weak references --- an object referenced only by proxy
! objects is deallocated -- but instead of requiring an explicit call to
! retrieve the object, the proxy transparently forwards all operations
! to the object as long as the object still exists. If the object is
! deallocated, attempting to use a proxy will cause a
! \exception{weakref.ReferenceError} exception to be raised.
! \begin{verbatim}
! proxy = weakref.proxy(obj)
! proxy.attr # Equivalent to obj.attr
! proxy.meth() # Equivalent to obj.meth()
! del obj
! proxy.attr # raises weakref.ReferenceError
! \end{verbatim}
\begin{seealso}
***************
*** 443,446 ****
--- 530,544 ----
\begin{itemize}
+ \item The \module{doctest} module provides a testing framework based
+ on running embedded examples in docstrings and comparing the results
+ against the expected output. Contributed by Tim Peters.
+
+ \item The \module{difflib} module contains a class,
+ \class{SequenceMatcher}, which compares two sequences and computes the
+ changes required to transform one sequence into the other. For
+ example, this module can be used to write a tool similar to the Unix
+ \program{diff} program, and in fact the sample program
+ \file{Tools/scripts/ndiff.py} demonstrates how to write such a script.
+
\item \module{curses.panel}, a wrapper for the panel library, part of
ncurses and of SYSV curses, was contributed by Thomas Gellekum. The
***************
*** 483,487 ****
--- 581,597 ----
\module{socket} module, contributed by Grant Edwards.
+ \item A new implementation-dependent function, \function{sys._getframe(\optional{depth})},
+ has been added to return a given frame object from the current call stack.
+ \function{sys._getframe()} returns the frame at the top of the call stack;
+ if the optional integer argument \var{depth} is supplied, the function returns the frame
+ that is \var{depth} calls below the top of the stack. For example, \code{sys._getframe(1)}
+ returns the caller's frame object.
+
+ This function is only present in CPython, not in Jython or the .NET
+ implementation. Use it for debugging, and resist the temptation to
+ put it into production code.
+
+
\end{itemize}
***************
*** 559,562 ****
--- 669,678 ----
containing the filename and line number of the error, a pleasant side
effect of the compiler reorganization done by Jeremy Hylton.
+
+ \item C extensions which import other modules have been changed to use
+ \function{PyImport_ImportModule()}, which means that they will use any
+ import hooks that have been installed. This is also encouraged for
+ third-party extensions that need to import some other module from C
+ code.
\item The size of the Unicode character database was shrunk by another
|