What’s New in Python 2.1¶
作者: | 上午。 Kuchling |
---|
Introduction¶
本文介绍了Python 2.1中的新功能。虽然在2.1中没有像Python 2.0中那么多的变化,但是在商店中仍然有一些令人惊喜的惊喜。2.1是通过使用Python增强提议(或PEP)引导的第一个版本,所以大多数相当大的更改伴随着PEP,提供了更完整的文档和设计理由的变化。本文不尝试完整地记录新功能,而只是简要介绍Python程序员的新功能。有关您特别感兴趣的任何新功能的更多详细信息,请参阅Python 2.1文档或特定PEP。
Python开发团队最近的一个目标是加快新版本的发布速度,每6至9个月发布一次新版本。2.1是第一个以这种更快的速度出现的版本,第一个alpha出现在1月,2.0的最终版本发布后3个月。
Python 2.1的最终版本是2001年4月17日发布的。
PEP 227: Nested Scopes¶
Python 2.1中最大的变化是Python的范围规则。在Python 2.0中,在任何给定的时间,最多有三个命名空间用于查找变量名:local,module-level和内建命名空间。这经常令人惊讶的人,因为它不符合他们的直觉预期。例如,嵌套递归函数定义不起作用:
def f():
...
def g(value):
...
return g(value-1) + 1
...
函数g()
将始终引发一个NameError
异常,因为名称g
的绑定不在其本地命名空间或模块级命名空间。这在实践中不是一个大问题(你多长时间递归定义这样的内部函数?),但这也使用lambda
语句clumsier,这在实践中是一个问题。在使用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中找到。
此更改可能会导致代码的一些兼容性问题,其中在模块级别使用相同的变量名称,而在包含更多函数定义的函数中则作为局部变量使用。这似乎不太可能,虽然,因为这样的代码本来是很容易阅读的首先。
One side effect of the change is that the from module import *
and exec
statements have been made illegal inside a function scope under certain conditions. Python参考手册一直说,从 模块 import *
法律在一个模块的顶层,但CPython解释器从来没有强制这一点。作为实现嵌套作用域的一部分,将Python源代码转换为字节码的编译器必须生成不同的代码来访问包含作用域中的变量。从 模块 导入 *
和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代码中很少使用(当它被使用时,它通常是一个糟糕的设计的迹象)。
兼容性问题导致逐步引入嵌套作用域;在Python 2.1中,它们在默认情况下未启用,但可以通过使用PEP 236中所述的future语句在模块中打开。(有关PEP 236.的进一步讨论,请参见以下部分)在Python 2.2中,嵌套的作用域将成为默认的作用域,并且没有办法将它们关闭,但用户将有2.1的生命周期来修复它们的引入导致的任何破坏。
也可以看看
- PEP 227 - 静态嵌套作用域
- 由Jeremy Hylton编写和实施。
PEP 236: __future__ Directives¶
对嵌套作用域的反应被广泛关注的是在2.1版本中破坏代码的危险,而且它足以使Pythoneers采取更保守的方法。该方法包括引入用于在版本N中启用可选功能的约定,其将在版本N + 1中变为强制的。
语法使用保留的模块名称__future__
的from...import
语句。可以通过以下语句启用嵌套作用域:
from __future__ import nested_scopes
虽然它看起来像一个正常的import
语句,但它不是;有关于这样的未来陈述可以被放置的严格规则。它们只能位于模块的顶部,并且必须位于任何Python代码或常规import
语句之前。这是因为这样的语句可以影响Python字节码编译器如何解析代码并生成字节码,因此它们必须在导致生成字节码的任何语句之前。
也可以看看
- PEP 236 - 返回
__future__
- 由Tim Peters编写,主要由Jeremy Hylton执行。
PEP 207: Rich Comparisons¶
在早期版本中,Python对于实现用户定义类和扩展类型的比较的支持非常简单。类可以实现一个给定类的两个实例的__cmp__()
方法,如果它们相等,则只能返回0;如果没有,则返回+1或-1;该方法不能引发异常或返回除布尔值之外的任何东西。Numeric Python的用户经常发现这个模型太弱和限制性,因为在数字Python所使用的数字处理程序中,能够执行两个矩阵的元素比较更有用,返回一个包含结果的矩阵每个元素的给定比较。如果两个矩阵具有不同的大小,则比较必须能够引发异常以用信号通知错误。
在Python 2.1中,添加了丰富的比较以支持这种需求。Python classes can now individually overload each of the <
, <=
, >
, >=
, ==
, and !=
operations. 新的魔法方法名称是:
操作 | 方法名称 |
---|---|
< | __lt__() |
<= | __le__() |
> | __gt__() |
>= | __ge__() |
== | __eq__() |
!= | __ne__() |
(魔法方法以相应的Fortran运算符.LT.
命名。.LE.
,&c。数字程序员几乎肯定很熟悉这些名字,并会发现它们很容易记住。)
每个魔法方法都是方法(self, other)
的形式,其中self
在操作符号的左手边,而other
将是右手侧的对象。例如,表达式A B
会导致A.__lt__(B)
每个魔法方法都可以返回任何东西:布尔值,矩阵,列表或任何其他Python对象。或者,如果比较是不可能,不一致或者无意义的,它们可以引发异常。
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 "!="
. 如果在没有可选的第三个参数的情况下调用,cmp()
将仅返回-1,0或+1,否则它将调用适当的方法,并可以返回任何Python对象。
C程序员也有相应的兴趣变化;在类型对象中有一个新的槽tp_richcmp
,以及用于执行给定的丰富比较的API。我不会在这里介绍C API,但会引用您PEP 207或2.1的C API文档,以获得相关功能的完整列表。
也可以看看
- PEP 207 - 丰富的比较
- 由Guido van Rossum撰写,大量基于David Ascher的早期工作,由Guido van Rossum执行。
PEP 230: Warning Framework¶
在其10年的存在,Python已经积累了一定数量的过时的模块和功能。很难知道某个特性是否可以安全删除,因为没有办法知道有多少代码使用它 - 也许没有程序依赖于该特性,或者许多特性。要以更结构化的方式启用删除旧的功能,添加了警告框架。当Python开发人员想要摆脱一个特性时,它将首先在下一个版本的Python中触发警告。以下Python版本可以删除该功能,用户将有一个完整的发布周期,以删除旧功能的使用。
Python 2.1添加了在此方案中使用的警告框架。它添加了一个warnings
模块,它提供了发出警告的功能,并过滤掉您不想显示的警告。第三方模块也可以使用此框架来废弃不再希望支持的旧功能。
例如,在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")
第一个参数是警告消息;可以使用附加的可选参数来指定特定的警告类别。
可以添加过滤器以禁用某些警告;可以将正则表达式模式应用于消息或模块名称,以便抑制警告。例如,您可能有一个程序使用regex
模块,而不想花时间将其转换为使用re
模块。可以通过呼叫抑制警告
import warnings
warnings.filterwarnings(action = 'ignore',
message='.*regex module is deprecated',
category=DeprecationWarning,
module = '__main__')
这将添加一个过滤器,该过滤器仅适用于在__main__
模块中触发的类DeprecationWarning
的警告,并应用正则表达式仅匹配有关regex
模块,并且会导致忽略此类警告。警告也可以只打印一次,每次执行错误代码时打印,或者变成异常,这将导致程序停止(除非异常被以通常的方式捕获)。
函数也添加到Python的C API中用于发出警告;有关详细信息,请参阅PEP 230或Python的API文档。
PEP 229: New Build System¶
当编译Python时,用户必须进入并编辑Modules/Setup
文件,以启用各种附加模块;默认设置相对较小,并且限于在大多数Unix平台上编译的模块。这意味着在具有许多更多功能的Unix平台上,最着名的是Linux,Python安装通常不包含所有可用的模块。
Python 2.0添加了Distutils,一组用于分发和安装扩展的模块。在Python 2.1中,Distutils用于编译扩展模块的大多数标准库,自动检测当前机器支持哪些扩展模块。希望这将使Python安装更容易,更有特色。
为了启用模块,不必编辑Modules/Setup
文件,Python源代码分发的顶层目录中的setup.py
脚本在构建时运行,并尝试通过检查系统上的模块和头文件来启用哪些模块。如果在Modules/Setup
中配置了模块,则setup.py
脚本将不会尝试编译该模块,而是将转到Modules/Setup
这提供了一种方法来指定特定平台所需的任何奇怪的命令行标志或库。
在构建机制的另一个意义深远的变化中,Neil Schemenauer重构了一些东西,所以Python现在使用一个不是递归的makefile,而不是顶层目录中的makefile和每个Python/
Parser/
,Objects/
和Modules/
子目录。这使得构建Python更快,也使得Makefile更黑,更简单。
也可以看看
- PEP 229 - 使用Distutils构建Python
- 由A.M.撰写和实施。 Kuchling。
PEP 205: Weak References¶
通过weakref
模块提供的弱引用在Python程序员工具箱中是一种次要但有用的新数据类型。
存储对对象的引用(例如,在字典或列表中)具有使该对象永久存活的副作用。有一些特定情况下,这种行为是不受欢迎的,对象缓存是最常见的,另一种是数据结构(如树)中的循环引用。
例如,考虑一个memoizing函数,通过将函数的参数及其结果存储在字典中来缓存另一个函数f(x)
的结果:
_cache = {}
def memoize(x):
if _cache.has_key(x):
return _cache[x]
retval = f(x)
# Cache the returned object
_cache[x] = retval
return retval
这个版本适用于简单的事情,如整数,但它有副作用; _cache
字典保存对返回值的引用,因此它们永远不会被释放,直到Python进程退出并清理这对整数不是很明显,但如果f()
返回一个对象或占用大量内存的数据结构,这可能是一个问题。
弱引用提供了一种实现高速缓存的方法,该方法不会使对象超出它们的时间。如果一个对象只能通过弱引用访问,该对象将被释放,弱引用现在将指示它所引用的对象不再存在。通过调用wr = weakref.ref(obj)创建对对象obj
。被引用的对象通过调用弱引用返回,就像它是一个函数:wr()
。如果对象不再存在,它将返回引用的对象,或None
。
这使得可以通过在缓存中存储弱引用来写入其缓存不保持对象活动的memoize()
函数。
_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
weakref
模块还允许创建代理对象,其行为类似于弱引用 - 仅由代理对象引用的对象被释放 - 但是代理不需要显式调用来检索对象,代理透明地将所有操作转发对象只要对象仍然存在。如果对象被释放,尝试使用代理将导致引发weakref.ReferenceError
异常。
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: Function Attributes¶
在Python 2.1中,函数现在可以附加任意信息。人们经常使用docstrings来保存函数和方法的信息,因为__doc__
属性是将任何信息附加到函数的唯一方法。例如,在Zope Web应用程序服务器中,通过使用docstring将函数标记为对于公共访问是安全的,并且在John Aycock的SPARK解析框架中,docstrings保存要解析的BNF语法的部分。这个重载是不幸的,因为docstrings真的打算保存一个函数的文档;例如,它意味着您不能正确地记录专用于Zope的功能。
现在可以使用常规Python语法在函数上设置和检索任意属性:
def f(): pass
f.publish = 1
f.secure = 1
f.grammar = "A ::= B (C D)*"
包含属性的字典可以作为函数的__dict__
来访问。与类实例的__dict__
属性不同,在函数中,实际上可以为__dict__
指定一个新字典,尽管新值仅限于常规Python字典;您不能是棘手的,并将其设置为UserDict
实例或任何其他随机对象的行为就像一个映射。
也可以看看
- PEP 232 - 功能属性
- 由Barry华沙撰写和实施。
PEP 235: Importing Modules on Case-Insensitive Platforms¶
某些操作系统具有不区分大小写的文件系统,MacOS和Windows是主要示例;在这些系统上,不可能区分文件名FILE.PY
和file.py
,即使它们将文件名存储在其原始大小写中(它们是case-保存)。
在Python 2.1中,import
语句将用于在不区分大小写的平台上模拟大小写敏感。默认情况下,Python会搜索第一个区分大小写的匹配,如果没有找到此类文件,则会引发ImportError
,因此导入 文件 t5 >
不会导入名为FILE.PY
的模块。通过在启动Python解释器之前设置 PYTHONCASEOK
PEP 217: Interactive Display Hook¶
当以交互方式使用Python解释器时,命令的输出使用内建repr()
函数显示。在Python 2.1中,变量sys.displayhook()
可以设置为可调用的对象,而不是repr()
。例如,您可以将其设置为特殊的漂亮打印功能:
>>> # 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 - 显示交互式使用的Hook
- 由Moshe Zadka编写和实施。
PEP 208: New Coercion Model¶
如何在C级别进行数字强制被显着修改。这将仅影响Python的C扩展的作者,允许他们更灵活地编写支持数字操作的扩展类型。
扩展类型现在可以在其PyTypeObject
结构中设置类型标志Py_TPFLAGS_CHECKTYPES
,以指示它们支持新的强制模型。在这样的扩展类型中,数字槽函数不能再假定它们将被传递两个相同类型的参数;而是可以传递两个不同类型的参数,然后可以执行自己的内部强制。如果槽函数传递了它不能处理的类型,则它可以通过返回对Py_NotImplemented
单值的引用来指示失败。然后将尝试另一种类型的数字函数,也许他们可以处理操作;如果其他类型也返回Py_NotImplemented
,则会引发TypeError
。用Python编写的数字方法也可以返回Py_NotImplemented
,导致解释器表现为该方法不存在(可能会产生一个TypeError
,可能尝试另一个对象的数字方法) 。
也可以看看
- PEP 208 - 重做强制模型
- 由Neil Schemenauer撰写和实施,主要基于Marc-AndréLemburg先前的工作。阅读这一点以了解现在如何在C级处理数值操作的细节。
PEP 241: Metadata in Python Packages¶
Python用户的一个常见的抱怨是没有所有Python模块的单一目录。T. Middleton的Vault of Parnassus在http://www.vex.net/parnassus/是Python模块的最大目录,但在Vaults注册软件是可选的,许多人不打扰。
作为解决问题的第一个小步骤,使用Distutils sdist命令打包的Python软件将包含一个名为PKG-INFO
的文件,其中包含有关包名称,版本和作者(元数据,编目术语)。PEP 241包含可以存在于PKG-INFO
文件中的字段的完整列表。随着人们开始使用Python 2.1打包他们的软件,越来越多的包将包括元数据,使得建立自动编目系统并进行实验成为可能。有了结果经验,也许可以设计一个非常好的目录,然后构建支持它到Python 2.2。例如,Distutils sdist和bdist _ *命令可以支持upload
选项,可以自动将您的包上传到目录服务器。
即使您不使用Python 2.1,也可以开始创建包含PKG-INFO
的包,因为新版本的Distutils将针对早期Python版本的用户。Distutils的版本1.0.2包括PEP 241中描述的更改,以及各种错误修复和增强。它可以从Distutils SIG在https://www.python.org/community/sigs/current/distutils-sig/获得。
New and Improved Modules¶
Ka-Ping Yee贡献了两个新模块:
inspect.py
,用于获取有关活Python代码的信息的模块和pydoc.py
,用于将docstring交互式转换为HTML或文本。作为奖励,现在自动安装的Tools/scripts/pydoc
使用pydoc.py
显示给定的Python模块,包或类名称的文档。例如,pydoc xml.dom
显示以下内容: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
还包括一个基于Tk的交互式帮助浏览器。pydoc
很容易上瘾;试试看!将两个不同的单元测试模块添加到标准库。由Tim Peters提供的
doctest
模块提供了一个基于在docstrings中运行嵌入式示例并将结果与预期输出进行比较的测试框架。PyUnit,由Steve Purcell提供,是一个单元测试框架,灵感来自JUnit,这又是Kent Beck的Smalltalk测试框架的改编。有关PyUnit的详细信息,请参见http://pyunit.sourceforge.net/。difflib
模块包含一个类SequenceMatcher
,它比较两个序列并计算将一个序列转换为另一个序列所需的变化。例如,此模块可用于编写类似于Unix diff程序的工具,实际上示例程序Tools/scripts/ndiff.py
演示如何写入这样的脚本。curses.panel
是面板库,ncurses和SYSV curses的一部分的封装,由Thomas Gellekum提供。面板库提供了具有深度附加特性的窗口。Windows可以在深度排序中移动得更高或更低,并且面板库可以确定面板重叠和哪些部分可见。PyXML包自从Python 2.0以来经历了几个版本,而Python 2.1包括更新版本的
xml
包。一些值得注意的更改包括支持Expat 1.2和更高版本,Expat解析器以Python支持的任何编码处理文件的能力,以及SAX,DOM和minidom
模块的各种错误修复。Ping还贡献了另一个钩子来处理未捕获的异常。
sys.excepthook()
可以设置为可调用对象。当任何try
...except
除外)未捕获异常时,异常将传递到sys.excepthook()
然后可以做任何它喜欢。在第九届Python会议上,Ping演示了这个钩子的应用程序:打印一个扩展的回溯,它不仅列出了堆栈帧,还列出了每个帧的函数参数和局部变量。time
模块中的各种函数(如asctime()
和localtime()
)需要一个浮点数参数,时代。这些函数的最常见的用法是使用当前时间,因此浮点参数是可选的;当未提供值时,将使用当前时间。例如,日志文件条目通常需要一个包含当前时间的字符串;在Python 2.1中,可以使用time.asctime()
,而不是之前需要的更长的time.asctime(time.localtime(time.time()))
。这一变化由Thomas Wouters提出和实施。
ftplib
模块现在默认以被动模式检索文件,因为被动模式更可能从防火墙后面工作。此请求来自Debian错误跟踪系统,因为其他Debian软件包使用ftplib
检索文件,然后不从防火墙后面工作。因为Netscape默认为被动模式,很少有人抱怨,但是如果被动模式不适合您的应用程序或网络设置,请在FTP对象上调用set_pasv(0)
以禁用被动模式。对原始套接字访问的支持已添加到由Grant Edwards提供的
socket
模块中。pstats
模块现在包含一个简单的交互式统计浏览器,用于显示Python程序的时序配置文件,当模块作为脚本运行时调用。供稿人:Eric S. Raymond。添加了一个新的实现相关函数
sys._getframe([depth])
,以从当前调用堆栈返回给定的帧对象。sys._getframe()
返回调用堆栈顶部的帧;如果提供了可选整数参数depth,则该函数返回在堆栈顶部以下的深度调用的帧。例如,sys._getframe(1)
返回调用者的框架对象。此函数仅在CPython中存在,而不在Jython或.NET实现中。使用它进行调试,并抵制把它放入生产代码的诱惑。
Other Changes and Fixes¶
由于较短的释放周期,Python 2.1中的较小更改相对较少。通过CVS更改日志进行搜索,应用了117个修补程序,修复了136个错误;这两个数字都可能是低估。一些更显着的变化是:
专用对象分配器现在可选地可用,应该比系统
malloc()
更快,并且具有更少的内存开销。分配器使用C的malloc()
函数来获取大型内存池,然后满足来自这些池的较小内存请求。它可以通过向configure脚本提供--with-pymalloc
选项来启用;有关实现细节,请参阅Objects/obmalloc.c
。C扩展模块的作者应该在启用对象分配器的情况下测试它们的代码,因为一些不正确的代码可能会中断,导致运行时的核心转储。在Python的C API中有一堆内存分配函数,以前只是C库的
malloc()
和free()
的别名,意味着如果你不小心称为不匹配函数,错误不会显着。当启用对象分配器时,这些函数不再是malloc()
和free()
的别名,调用错误的函数释放内存会让你核心转储。例如,如果使用PyMem_New()
分配内存,则必须使用PyMem_Del()
,而不是free()
释放内存。Python中包含的几个模块违背了这一点,必须修复;无疑有更多的第三方模块将有同样的问题。对象分配器由Vladimir Marangozov贡献。
面向行的文件I / O的速度已经得到改进,因为人们经常抱怨它缺乏速度,并且因为它经常被用作一个天真的基准。因此,文件对象的
readline()
方法被重写得更快。根据C库的getc()
有多慢,但是大约66%,并且在某些特定操作系统上可能快得多,所以加速的确切数量将在平台之间变化。Tim Peters对comp.lang.python的讨论提出了许多基准和编码。文件对象的新模块和方法也被添加,由Jeff Epler贡献。新方法
xreadlines()
类似于现有的xrange()
内建。xreadlines()
返回一个只支持迭代的不透明序列对象,每次迭代都读取一行,但不会将整个文件读入内存,因为现有的readlines()
你会这样使用它:for line in sys.stdin.xreadlines(): # ... do something for each line ... ...
有关行I / O更改的更全面讨论,请参阅2001年1月1-15日的的python-dev摘要https://mail.python.org/pipermail/python-dev/2001-January/ 。
一个新的方法,
popitem()
,被添加到字典,以允许破坏性地迭代通过字典的内容;这对于大型字典可以更快,因为不需要构造包含所有键或值的列表。D.popitem()
removes a random(key, value)
pair from the dictionaryD
and returns it as a 2-tuple. 这主要由Tim Peters和Guido van Rossum在Moshe Zadka的建议和初步补丁之后实施。模块现在可以控制在
从 模块 导入 *
使用时导入哪些名称,通过定义包含要导入的名称列表的__all__
属性。一个常见的抱怨是,如果模块导入来自sys
或string
,从 模块 import *
将会将它们添加到导入模块的命名空间。要解决这个问题,只需在__all__
中列出公共名称即可:# List public names __all__ = ['Database', 'open']
这个补丁的更严格的版本由Ben Wolfson首先提出和实现,但是在一些python-dev讨论之后,检查了较弱的最终版本。
将
repr()
应用于以前用于不可打印字符的八进制转义字符串;例如,换行符是'\012'
。这是Python的C祖先的遗迹,但是今天的八进制是非常少的实际使用。Ka-Ping Yee建议使用十六进制转义而不是八进制转义,并使用适当字符的\n
,\t
,\r
,并实现了这种新的格式。在编译时检测到的语法错误现在可以引发包含错误的文件名和行号的异常,这是Jeremy Hylton完成的编译器重组的一个愉快的副作用。
导入其他模块的C扩展已更改为使用
PyImport_ImportModule()
,这意味着它们将使用已安装的任何导入钩子。对于需要从C代码导入其他模块的第三方扩展,也鼓励这样做。由于Fredrik Lundh,Unicode字符数据库的大小缩减了340K。
提供了一些新的端口:MacOS X(由Steven Majewski提供),Cygwin(Jason Tishler提供); RISCOS(Dietmar Schwertberger); Unixware 7(由Billy G. Allie)。
还有通常的小错误修复,小内存泄漏,docstring编辑和其他调整,太长的值得列出;请参阅CVS日志了解完整详细信息(如果需要)。
Acknowledgements¶
作者感谢以下人士就本文的各种草案提出建议:Graeme Cross,David Goodger,Jay Graves,Michael Hudson,Marc-AndréLemburg,Fredrik Lundh,Neil Schemenauer,Thomas Wouters。