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:
运算 |
方法名称 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
(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/.
新增和改进的模块¶
Ka-Ping Yee contributed two new modules:
inspect.py
, a module for getting information about live Python code, andpydoc.py
, a module for interactively converting docstrings to HTML or text. As a bonus,Tools/scripts/pydoc
, which is now automatically installed, usespydoc.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 programTools/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 theminidom
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 anytry
...except
blocks, the exception will be passed tosys.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 asasctime()
andlocaltime()
, 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 lengthiertime.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 useftplib
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, callset_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'smalloc()
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; seeObjects/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()
andfree()
, 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 ofmalloc()
andfree()
any more, and calling the wrong function to free memory will get you a core dump. For example, if memory was allocated usingPyMem_New()
, it has to be freed usingPyMem_Del()
, notfree()
. 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'sgetc()
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 existingxrange()
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 existingreadlines()
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 dictionaryD
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 assys
orstring
,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.