Python 2.1 有什么新变化
***********************

作者:
   A.M. Kuchling


概述
====

本文介绍了 Python 2.1 的新增特性。 虽然 2.1 的改变没有 Python 2.0 那么
多，但是仍然有一些令人惊喜的东西。 2.1 是第一个使用 Python 增强提议，
即 PEP 来进行引导的发行版，因此大部分重要的改变都有相应的 PEP 来提供有
关改变的更完整文档和设计思路。 本文并未试图完整记录所有的新特性，而是
为 Python 程序员提供新特性的简单概览。 请参阅 Python 2.1 文档，或特定
的 PEP，获取针对你感兴趣的任何新特性的更多细节。

Python 开发团队的一个近期目标是加速新发行版的步调，使得每 6 到 9 个月
就有一个新发行版。 2.1 是基于这个新步调推出的第一个发行版，第一个内测
版将于一月发布，即 2.0 最终版发布 3 个月之后。

Python 2.1 的最终版本于2001年4月17日发布。


PEP 227: 嵌套的作用域
=====================

Python 2.1 中的最大改变是 Python 的作用域规则。 在 Python 2.0 中，任意
给定的时刻至多使用三个命名空间来查找变量名称：局部、模块和内置命名空间
。 这往往会导致令人吃惊的结果因为它与人们直觉上的预期不相匹配。 例如，
一个嵌套的递归函数将不起作用:

   def f():
       ...
       def g(value):
           ...
           return g(value-1) + 1
       ...

函数 "g()" 将总是引发 "NameError" 异常，因为名称 "g" 的绑定既不在局部
命名空间中也不在模块级命名空间中。 这在实践上不会有太大问题（你会经常
这样递归地定义内部函数吗？），但是这也会让 "lambda" 表达式的使用更为笨
拙，这在实践上是有问题的。 在使用了 "lambda" 的代码中你经常能发现局部
变量通过作为参数的默认值被拷贝。

   def find(self, name):
       "Return list of any entries equal to 'name'"
       L = filter(lambda x, name=name: x == name,
                  self.list_attribute)
       return L

结果将会严重损害以高度函数式风格编写的 Python 代码的可读性。

Python 2.1 最显著的改变是增加了静态作用域这一语言特征来解决此问题。 作
为它的第一项影响，在上述示例中的 "name=name" 默认参数现在将不再必要。
简单地说，当一个函数内部的给定变量名没有被赋值时（通过赋值语句，或者
"def", "class" 或 "import" 语句），对该变量的引用将在外层作用域的局部
命名空间中查找。 对于该规则的更详细解释，以及具体实现的分析，请参阅相
应的 PEP。

对于同时在模块层级和包含下层函数定义的函数内部局部变量使用了相同变量名
的代码来说这项改变可能会导致一些兼容性问题。 不过这看来不太可能发生，
因为阅读这样的代码本来就会相当令人困惑。

此项改变的一个附带影响是在特定条件下函数作用域内部 "from module import
*" 和 "exec" 语句将不允许使用。 Python 参考手册已经写明 "from module
import *" 仅在模块最高层级上是可用的，但此前 CPython 解释器从未强制实
施此规则。 作为嵌套作用域具体实现的一部分，将 Python 源码转为字节码的
编译器会生成不同的代码来访问某个包含作用域内的变量。 "from module
import *" 和 "exec" 会使得编译器无法正确执行，因为它们会向局部命名空间
添加在编译时还不存在的名称。 为此，如果一个函数包含带有自由变量的函数
定义或 "lambda" 表达式，编译器将通过引发 "SyntaxError" 异常来提示。

为了使前面的解释更清楚，下面是一个例子:

   x = 1
   def f():
       # The next line is a syntax error
       exec 'x=2'
       def g():
           return x

包含 "exec" 语句的第 4 行有语法错误，因为 "exec" 将定义一个名为 "x" 的
新局部变量，它的值应当被 "g()" 访问。

这应该不会是太大的限制，因为 "exec" 在多数 Python 代码中都极少被使用（
而当它被使用时，往往也是个存在糟糕设计的信号）。

Compatibility concerns have led to nested scopes being introduced
gradually; in Python 2.1, they aren't enabled by default, but can be
turned on within a module by using a future statement as described in
**PEP 236**.  (See the following section for further discussion of
**PEP 236**.)  In Python 2.2, nested scopes will become the default
and there will be no way to turn them off, but users will have had all
of 2.1's lifetime to fix any breakage resulting from their
introduction.

参见:

  **PEP 227** - 静态嵌套作用域
     由 Jeremy Hylton 撰写并实现。


PEP 236: __future__ 指令
========================

The reaction to nested scopes was widespread concern about the dangers
of breaking code with the 2.1 release, and it was strong enough to
make the Pythoneers take a more conservative approach.  This approach
consists of introducing a convention for enabling optional
functionality in release N that will become compulsory in release N+1.

The syntax uses a "from...import" statement using the reserved module
name "__future__".  Nested scopes can be enabled by the following
statement:

   from __future__ import nested_scopes

While it looks like a normal "import" statement, it's not; there are
strict rules on where such a future statement can be put. They can
only be at the top of a module, and must precede any Python code or
regular "import" statements.  This is because such statements can
affect how the Python bytecode compiler parses code and generates
bytecode, so they must precede any statement that will result in
bytecodes being produced.

参见:

  **PEP 236** - 回到 "__future__"
     由 Tim Peters 撰写，主要由 Jeremy Hylton 实现。


PEP 207: 富比较
===============

In earlier versions, Python's support for implementing comparisons on
user-defined classes and extension types was quite simple. Classes
could implement a "__cmp__()" method that was given two instances of a
class, and could only return 0 if they were equal or +1 or -1 if they
weren't; the method couldn't raise an exception or return anything
other than a Boolean value.  Users of Numeric Python often found this
model too weak and restrictive, because in the number-crunching
programs that numeric Python is used for, it would be more useful to
be able to perform elementwise comparisons of two matrices, returning
a matrix containing the results of a given comparison for each
element.  If the two matrices are of different sizes, then the compare
has to be able to raise an exception to signal the error.

In Python 2.1, rich comparisons were added in order to support this
need. Python classes can now individually overload each of the "<",
"<=", ">", ">=", "==", and "!=" operations.  The new magic method
names are:

+-------------+------------------+
| 运算        | 方法名称         |
|=============|==================|
| "<"         | "__lt__()"       |
+-------------+------------------+
| "<="        | "__le__()"       |
+-------------+------------------+
| ">"         | "__gt__()"       |
+-------------+------------------+
| ">="        | "__ge__()"       |
+-------------+------------------+
| "=="        | "__eq__()"       |
+-------------+------------------+
| "!="        | "__ne__()"       |
+-------------+------------------+

(The magic methods are named after the corresponding Fortran operators
".LT.". ".LE.", &c.  Numeric programmers are almost certainly quite
familiar with these names and will find them easy to remember.)

Each of these magic methods is of the form "method(self, other)",
where "self" will be the object on the left-hand side of the operator,
while "other" will be the object on the right-hand side.  For example,
the expression "A < B" will cause "A.__lt__(B)" to be called.

Each of these magic methods can return anything at all: a Boolean, a
matrix, a list, or any other Python object.  Alternatively they can
raise an exception if the comparison is impossible, inconsistent, or
otherwise meaningless.

The built-in "cmp(A,B)" function can use the rich comparison
machinery, and now accepts an optional argument specifying which
comparison operation to use; this is given as one of the strings
""<"", ""<="", "">"", "">="", ""=="", or ""!="".  If called without
the optional third argument, "cmp()" will only return -1, 0, or +1 as
in previous versions of Python; otherwise it will call the appropriate
method and can return any Python object.

There are also corresponding changes of interest to C programmers;
there's a new slot "tp_richcmp" in type objects and an API for
performing a given rich comparison.  I won't cover the C API here, but
will refer you to **PEP 207**, or to 2.1's C API documentation, for
the full list of related functions.

参见:

  **PEP 207** - 富比较
     由 Guido van Rossum 编写，大量参考 David Ascher 的先期工作，并由
     Guido van Rossum 实现。


PEP 230: 警告框架
=================

Over its 10 years of existence, Python has accumulated a certain
number of obsolete modules and features along the way.  It's difficult
to know when a feature is safe to remove, since there's no way of
knowing how much code uses it --- perhaps no programs depend on the
feature, or perhaps many do.  To enable removing old features in a
more structured way, a warning framework was added. When the Python
developers want to get rid of a feature, it will first trigger a
warning in the next version of Python.  The following Python version
can then drop the feature, and users will have had a full release
cycle to remove uses of the old feature.

Python 2.1 adds the warning framework to be used in this scheme.  It
adds a "warnings" module that provide functions to issue warnings, and
to filter out warnings that you don't want to be displayed. Third-
party modules can also use this framework to deprecate old features
that they no longer wish to support.

例如，在 Python 2.1 中 "regex" 模块已被弃用，因此导入它时会打印一条警
告信息:

   >>> import regex
   __main__:1: DeprecationWarning: the regex module
            is deprecated; please use the re module
   >>>

警告可以通过调用 "warnings.warn()" 函数来发出:

   warnings.warn("feature X no longer supported")

第一个形参是警告消息；额外的可选形参可被用来指定一个专门的警告类别。

Filters can be added to disable certain warnings; a regular expression
pattern can be applied to the message or to the module name in order
to suppress a warning.  For example, you may have a program that uses
the "regex" module and not want to spare the time to convert it to use
the "re" module right now.  The warning can be suppressed by calling

   import warnings
   warnings.filterwarnings(action = 'ignore',
                           message='.*regex module is deprecated',
                           category=DeprecationWarning,
                           module = '__main__')

This adds a filter that will apply only to warnings of the class
"DeprecationWarning" triggered in the "__main__" module, and applies a
regular expression to only match the message about the "regex" module
being deprecated, and will cause such warnings to be ignored.
Warnings can also be printed only once, printed every time the
offending code is executed, or turned into exceptions that will cause
the program to stop (unless the exceptions are caught in the usual
way, of course).

Functions were also added to Python's C API for issuing warnings;
refer to PEP 230 or to Python's API documentation for the details.

参见:

  **PEP 5** - 语言演化的准则
     Written by Paul Prescod, to specify procedures to be followed
     when removing old features from Python.  The policy described in
     this PEP hasn't been officially adopted, but the eventual policy
     probably won't be too different from Prescod's proposal.

  **PEP 230** - 警告框架
     由 Guido van Rossum 撰写并实现。


PEP 229: 新的构建系统
=====================

When compiling Python, the user had to go in and edit the
"Modules/Setup" file in order to enable various additional modules;
the default set is relatively small and limited to modules that
compile on most Unix platforms. This means that on Unix platforms with
many more features, most notably Linux, Python installations often
don't contain all useful modules they could.

Python 2.0 added the Distutils, a set of modules for distributing and
installing extensions.  In Python 2.1, the Distutils are used to
compile much of the standard library of extension modules,
autodetecting which ones are supported on the current machine.  It's
hoped that this will make Python installations easier and more
featureful.

Instead of having to edit the "Modules/Setup" file in order to enable
modules, a "setup.py" script in the top directory of the Python source
distribution is run at build time, and attempts to discover which
modules can be enabled by examining the modules and header files on
the system.  If a module is configured in "Modules/Setup", the
"setup.py" script won't attempt to compile that module and will defer
to the "Modules/Setup" file's contents.  This provides a way to
specific any strange command-line flags or libraries that are required
for a specific platform.

In another far-reaching change to the build mechanism, Neil
Schemenauer restructured things so Python now uses a single makefile
that isn't recursive, instead of makefiles in the top directory and in
each of the "Python/", "Parser/", "Objects/", and "Modules/"
subdirectories.  This makes building Python faster and also makes
hacking the Makefiles clearer and simpler.

参见:

  **PEP 229** - 使用 Distutils 来构建 Python
     由 A.M. Kuchling 撰写并实现。


PEP 205: 弱引用
===============

Weak references, available through the "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 "f(x)" by storing the function's argument and its
result in a dictionary:

   _cache = {}
   def memoize(x):
       if _cache.has_key(x):
           return _cache[x]

       retval = f(x)

       # Cache the returned object
       _cache[x] = retval

       return retval

This version works for simple things such as integers, but it has a
side effect; the "_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 "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 *obj* is created by calling "wr
= weakref.ref(obj)".  The object being referred to is returned by
calling the weak reference as if it were a function: "wr()".  It will
return the referenced object, or "None" if the object no longer
exists.

This makes it possible to write a "memoize()" function whose cache
doesn't keep objects alive, by storing weak references in the cache.

   _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

The "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
"weakref.ReferenceError" exception to be raised.

   proxy = weakref.proxy(obj)
   proxy.attr   # Equivalent to obj.attr
   proxy.meth() # Equivalent to obj.meth()
   del obj
   proxy.attr   # raises weakref.ReferenceError

参见:

  **PEP 205** - 弱引用
     由 Fred L. Drake, Jr 撰写并实现。


PEP 232: 函数属性
=================

In Python 2.1, functions can now have arbitrary information attached
to them. People were often using docstrings to hold information about
functions and methods, because the "__doc__" attribute was the only
way of attaching any information to a function.  For example, in the
Zope Web application server, functions are marked as safe for public
access by having a docstring, and in John Aycock's SPARK parsing
framework, docstrings hold parts of the BNF grammar to be parsed.
This overloading is unfortunate, since docstrings are really intended
to hold a function's documentation; for example, it means you can't
properly document functions intended for private use in Zope.

Arbitrary attributes can now be set and retrieved on functions using
the regular Python syntax:

   def f(): pass

   f.publish = 1
   f.secure = 1
   f.grammar = "A ::= B (C D)*"

The dictionary containing attributes can be accessed as the function's
"__dict__". Unlike the "__dict__" attribute of class instances, in
functions you can actually assign a new dictionary to "__dict__",
though the new value is restricted to a regular Python dictionary; you
*can't* be tricky and set it to a "UserDict" instance, or any other
random object that behaves like a mapping.

参见:

  **PEP 232** - 函数属性
     由 Barry Warsaw 撰写并实现


PEP 235: 在大小写不敏感的平台上导入模块
=======================================

Some operating systems have filesystems that are case-insensitive,
MacOS and Windows being the primary examples; on these systems, it's
impossible to distinguish the filenames "FILE.PY" and "file.py", even
though they do store the file's name  in its original case (they're
case-preserving, too).

In Python 2.1, the "import" statement will work to simulate case-
sensitivity on case-insensitive platforms.  Python will now search for
the first case-sensitive match by default, raising an "ImportError" if
no such file is found, so "import file" will not import a module named
"FILE.PY". Case-insensitive matching can be requested by setting the
"PYTHONCASEOK" environment variable before starting the Python
interpreter.


PEP 217: 交互模式显示钩子
=========================

When using the Python interpreter interactively, the output of
commands is displayed using the built-in "repr()" function. In Python
2.1, the variable "sys.displayhook()" can be set to a callable object
which will be called instead of "repr()". For example, you can set it
to a special pretty-printing function:

   >>> # Create a recursive data structure
   ... L = [1,2,3]
   >>> L.append(L)
   >>> L # Show Python's default output
   [1, 2, 3, [...]]
   >>> # Use pprint.pprint() as the display function
   ... import sys, pprint
   >>> sys.displayhook = pprint.pprint
   >>> L
   [1, 2, 3,  <Recursion on list with id=135143996>]
   >>>

参见:

  **PEP 217** - 用于交互模式的显示钩子
     由 Moshe Zadka 撰写并实现


PEP 208: 新的强制转换模型
=========================

How numeric coercion is done at the C level was significantly
modified.  This will only affect the authors of C extensions to
Python, allowing them more flexibility in writing extension types that
support numeric operations.

Extension types can now set the type flag "Py_TPFLAGS_CHECKTYPES" in
their "PyTypeObject" structure to indicate that they support the new
coercion model. In such extension types, the numeric slot functions
can no longer assume that they'll be passed two arguments of the same
type; instead they may be passed two arguments of differing types, and
can then perform their own internal coercion. If the slot function is
passed a type it can't handle, it can indicate the failure by
returning a reference to the "Py_NotImplemented" singleton value. The
numeric functions of the other type will then be tried, and perhaps
they can handle the operation; if the other type also returns
"Py_NotImplemented", then a "TypeError" will be raised.  Numeric
methods written in Python can also return "Py_NotImplemented", causing
the interpreter to act as if the method did not exist (perhaps raising
a "TypeError", perhaps trying another object's numeric methods).

参见:

  **PEP 208** - 改写强制转换模型
     Written and implemented by Neil Schemenauer, heavily based upon
     earlier work by Marc-André Lemburg.  Read this to understand the
     fine points of how numeric operations will now be processed at
     the C level.


PEP 241: Python 包中的元数据
============================

A common complaint from Python users is that there's no single catalog
of all the Python modules in existence.  T. Middleton's Vaults of
Parnassus at http://www.vex.net/parnassus/ are the largest catalog of
Python modules, but registering software at the Vaults is optional,
and many people don't bother.

As a first small step toward fixing the problem, Python software
packaged using the Distutils **sdist** command will include a file
named "PKG-INFO" containing information about the package such as its
name, version, and author (metadata, in cataloguing terminology).
**PEP 241** contains the full list of fields that can be present in
the "PKG-INFO" file.  As people began to package their software using
Python 2.1, more and more packages will include metadata, making it
possible to build automated cataloguing systems and experiment with
them.  With the result experience, perhaps it'll be possible to design
a really good catalog and then build support for it into Python 2.2.
For example, the Distutils **sdist** and **bdist_*** commands could
support an "upload" option that would automatically upload your
package to a catalog server.

You can start creating packages containing "PKG-INFO" even if you're
not using Python 2.1, since a new release of the Distutils will be
made for users of earlier Python versions.  Version 1.0.2 of the
Distutils includes the changes described in **PEP 241**, as well as
various bugfixes and enhancements.  It will be available from the
Distutils SIG at https://www.python.org/community/sigs/current
/distutils-sig/.

参见:

  **PEP 241** - 针对 Python 软件包的元数据
     由 A.M. Kuchling 撰写并实现。

  **PEP 243** - 模块仓库上传机制
     由 Sean Reifschneider 撰写，这个 PEP 草案描述了用于将 Python 软件
     包上传到一个中心服务器的建议机制。


新增和改进的模块
================

* Ka-Ping Yee contributed two new modules: "inspect.py", a module for
  getting information about live Python code, and "pydoc.py", a module
  for interactively converting docstrings to HTML or text.  As a
  bonus, "Tools/scripts/pydoc", which is now automatically installed,
  uses "pydoc.py" to display documentation given a Python module,
  package, or class name.  For example, "pydoc xml.dom" displays the
  following:

     Python Library Documentation: package xml.dom in xml

     NAME
         xml.dom - W3C Document Object Model implementation for Python.

     FILE
         /usr/local/lib/python2.1/xml/dom/__init__.pyc

     DESCRIPTION
         The Python mapping of the Document Object Model is documented in the
         Python Library Reference in the section on the xml.dom package.

         This package contains the following modules:
           ...

  "pydoc" also includes a Tk-based interactive help browser.   "pydoc"
  quickly becomes addictive; try it out!

* Two different modules for unit testing were added to the standard
  library. The "doctest" module, contributed by Tim Peters, provides a
  testing framework based on running embedded examples in docstrings
  and comparing the results against the expected output.  PyUnit,
  contributed by Steve Purcell, is a unit testing framework inspired
  by JUnit, which was in turn an adaptation of Kent Beck's Smalltalk
  testing framework.  See http://pyunit.sourceforge.net/ for more
  information about PyUnit.

* The "difflib" module contains a 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 **diff** program, and in
  fact the sample program "Tools/scripts/ndiff.py" demonstrates how to
  write such a script.

* "curses.panel", a wrapper for the panel library, part of ncurses and
  of SYSV curses, was contributed by Thomas Gellekum.  The panel
  library provides windows with the additional feature of depth.
  Windows can be moved higher or lower in the depth ordering, and the
  panel library figures out where panels overlap and which sections
  are visible.

* The PyXML package has gone through a few releases since Python 2.0,
  and Python 2.1 includes an updated version of the "xml" package.
  Some of the noteworthy changes include support for Expat 1.2 and
  later versions, the ability for Expat parsers to handle files in any
  encoding supported by Python, and various bugfixes for SAX, DOM, and
  the "minidom" module.

* Ping also contributed another hook for handling uncaught exceptions.
  "sys.excepthook()" can be set to a callable object.  When an
  exception isn't caught by any "try"..."except" blocks, the exception
  will be passed to "sys.excepthook()", which can then do whatever it
  likes.  At the Ninth Python Conference, Ping demonstrated an
  application for this hook: printing an extended traceback that not
  only lists the stack frames, but also lists the function arguments
  and the local variables for each frame.

* Various functions in the "time" module, such as "asctime()" and
  "localtime()", require a floating point argument containing the time
  in seconds since the epoch.  The most common use of these functions
  is to work with the current time, so the floating point argument has
  been made optional; when a value isn't provided, the current time
  will be used.  For example, log file entries usually need a string
  containing the current time; in Python 2.1, "time.asctime()" can be
  used, instead of the lengthier
  "time.asctime(time.localtime(time.time()))" that was previously
  required.

  This change was proposed and implemented by Thomas Wouters.

* The "ftplib" module now defaults to retrieving files in passive
  mode, because passive mode is more likely to work from behind a
  firewall.  This request came from the Debian bug tracking system,
  since other Debian packages use "ftplib" to retrieve files and then
  don't work from behind a firewall. It's deemed unlikely that this
  will cause problems for anyone, because Netscape defaults to passive
  mode and few people complain, but if passive mode is unsuitable for
  your application or network setup, call "set_pasv(0)" on FTP objects
  to disable passive mode.

* Support for raw socket access has been added to the "socket" module,
  contributed by Grant Edwards.

* The "pstats" module now contains a simple interactive statistics
  browser for displaying timing profiles for Python programs, invoked
  when the module is run as a script.  Contributed by  Eric S.
  Raymond.

* A new implementation-dependent function, "sys._getframe([depth])",
  has been added to return a given frame object from the current call
  stack. "sys._getframe()" returns the frame at the top of the call
  stack;  if the optional integer argument *depth* is supplied, the
  function returns the frame that is *depth* calls below the top of
  the stack.  For example, "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.


其他的改变和修正
================

There were relatively few smaller changes made in Python 2.1 due to
the shorter release cycle.  A search through the CVS change logs turns
up 117 patches applied, and 136 bugs fixed; both figures are likely to
be underestimates.  Some of the more notable changes are:

* A specialized object allocator is now optionally available, that
  should be faster than the system "malloc()" and have less memory
  overhead.  The allocator uses C's "malloc()" function to get large
  pools of memory, and then fulfills smaller memory requests from
  these pools.  It can be enabled by providing the "--with-pymalloc"
  option to the **configure** script; see "Objects/obmalloc.c" for the
  implementation details.

  Authors of C extension modules should test their code with the
  object allocator enabled, because some incorrect code may break,
  causing core dumps at runtime. There are a bunch of memory
  allocation functions in Python's C API that have previously been
  just aliases for the C library's "malloc()" and "free()", meaning
  that if you accidentally called mismatched functions, the error
  wouldn't be noticeable.  When the object allocator is enabled, these
  functions aren't aliases of "malloc()" and "free()" any more, and
  calling the wrong function to free memory will get you a core dump.
  For example, if memory was allocated using "PyMem_New()", it has to
  be freed using "PyMem_Del()", not "free()".  A few modules included
  with Python fell afoul of this and had to be fixed; doubtless there
  are more third-party modules that will have the same problem.

  The object allocator was contributed by Vladimir Marangozov.

* The speed of line-oriented file I/O has been improved because people
  often complain about its lack of speed, and because it's often been
  used as a naïve benchmark.  The "readline()" method of file objects
  has therefore been rewritten to be much faster.  The exact amount of
  the speedup will vary from platform to platform depending on how
  slow the C library's "getc()" was, but is around 66%, and
  potentially much faster on some particular operating systems. Tim
  Peters did much of the benchmarking and coding for this change,
  motivated by a discussion in comp.lang.python.

  A new module and method for file objects was also added, contributed
  by Jeff Epler. The new method, "xreadlines()", is similar to the
  existing "xrange()" built-in.  "xreadlines()" returns an opaque
  sequence object that only supports being iterated over, reading a
  line on every iteration but not reading the entire file into memory
  as the existing "readlines()" method does. You'd use it like this:

     for line in sys.stdin.xreadlines():
         # ... do something for each line ...
         ...

  For a fuller discussion of the line I/O changes, see the python-dev
  summary for January 1--15, 2001 at https://mail.python.org/pipermail
  /python-dev/2001-January/.

* A new method, "popitem()", was added to dictionaries to enable
  destructively iterating through the contents of a dictionary; this
  can be faster for large dictionaries because there's no need to
  construct a list containing all the keys or values. "D.popitem()"
  removes a random "(key, value)" pair from the dictionary "D" and
  returns it as a 2-tuple.  This was implemented mostly by Tim Peters
  and Guido van Rossum, after a suggestion and preliminary patch by
  Moshe Zadka.

* Modules can now control which names are imported when "from module
  import *" is used, by defining an "__all__" attribute containing a
  list of names that will be imported.  One common complaint is that
  if the module imports other modules such as "sys" or "string", "from
  module import *" will add them to the importing module's namespace.
  To fix this, simply list the public names in "__all__":

     # List public names
     __all__ = ['Database', 'open']

  A stricter version of this patch was first suggested and implemented
  by Ben Wolfson, but after some python-dev discussion, a weaker final
  version was checked in.

* Applying "repr()" to strings previously used octal escapes for non-
  printable characters; for example, a newline was "'\012'".  This was
  a vestigial trace of Python's C ancestry, but today octal is of very
  little practical use.  Ka-Ping Yee suggested using hex escapes
  instead of octal ones, and using the "\n", "\t", "\r" escapes for
  the appropriate characters, and implemented this new formatting.

* Syntax errors detected at compile-time can now raise exceptions
  containing the filename and line number of the error, a pleasant
  side effect of the compiler reorganization done by Jeremy Hylton.

* C extensions which import other modules have been changed to use
  "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.

* The size of the Unicode character database was shrunk by another
  340K thanks to Fredrik Lundh.

* Some new ports were contributed: MacOS X (by Steven Majewski),
  Cygwin (by Jason Tishler); RISCOS (by Dietmar Schwertberger);
  Unixware 7  (by Billy G. Allie).

此外还有一份由次要的程序错误修复、次要的内存泄漏、文档字符串编辑和其他
调整组成的常规清单，因过于冗长而不值得逐项列出；如果你想了解完整细节请
参阅 CVS 日志。


致谢
====

作者感谢以下人员对本文的各种草案提出建议： Graeme Cross, David
Goodger, Jay Graves, Michael Hudson, Marc-André Lemburg, Fredrik
Lundh, Neil Schemenauer, Thomas Wouters.
