python 2.1的新功能

作者

库克林

介绍

本文解释了Python2.1中的新特性。虽然2.1中的变化不如Python2.0中的变化那么多,但仍有一些令人愉快的惊喜。2.1是第一个通过使用python增强方案(peps)进行指导的版本,因此大多数较大的变更都伴随着peps,它提供了更完整的文档和变更的设计理由。本文并不试图完整地记录新特性,而是简单地为Python程序员提供新特性的概述。有关您特别感兴趣的任何新特性的更多详细信息,请参阅python 2.1文档或特定的PEP。

Python开发团队最近的一个目标是加快新版本的发布速度,每6到9个月发布一次新版本。2.1是以更快的速度发布的第一个版本,第一个alpha出现在1月,即2.0最终版本发布3个月后。

python 2.1的最终版本是在2001年4月17日发布的。

PEP 227:嵌套范围

python 2.1中最大的变化是对python的作用域规则的更改。在Python2.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 在上面的例子中,默认参数现在是不必要的。简单地说,当一个给定的变量名没有在一个函数中赋值时(通过赋值,或 defclassimport 语句),将在封闭范围的本地命名空间中查找对变量的引用。在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

第4行包含 exec 语句是语法错误,因为 exec 将定义一个名为 x 其值应由 g() .

这不应该有太大的限制,因为 exec 在大多数Python代码中很少使用(而且在使用时,它通常是糟糕设计的标志)。

兼容性问题导致了嵌套作用域的逐步引入;在Python2.1中,默认情况下不启用它们,但可以通过使用中描述的未来语句在模块内启用它们。 PEP 236 . (有关进一步讨论,请参见以下章节 PEP 236 )在python 2.2中,嵌套作用域将成为默认值,并且无法关闭它们,但是用户将有2.1的全部生命周期来修复由于其引入而导致的任何损坏。

参见

PEP 227 -静态嵌套作用域

由Jeremy Hylton编写并实施。

PEP 236: __future__ 指令

对嵌套范围的反应是对2.1版本中破坏代码的危险性的广泛关注,它足以使pythoneers采取更加保守的方法。这种方法包括引入一个在版本n中启用可选功能的约定,这在版本n+1中是强制的。

语法使用 from...import 使用保留模块名称的语句 __future__ . 嵌套范围可以通过以下语句启用::

from __future__ import nested_scopes

虽然看起来很正常 import 声明,事实并非如此;对于这种未来的声明可以放在哪里有严格的规则。它们只能位于模块的顶部,并且必须位于任何Python代码或常规代码之前 import 声明。这是因为这样的语句会影响Python字节码编译器解析代码和生成字节码的方式,所以它们必须位于任何将导致生成字节码的语句之前。

参见

PEP 236 - Back to the __future__

由蒂姆·彼得斯撰写,主要由杰里米·希尔顿执行。

PEP 207:丰富的比较

在早期版本中,Python对用户定义类和扩展类型实现比较的支持非常简单。类可以实现 __cmp__() 方法,该方法被赋予一个类的两个实例,如果它们相等,则只能返回0;如果它们不相等,则只能返回+1或-1;该方法不能引发异常或返回布尔值以外的任何值。numeric python的用户经常发现这个模型过于脆弱和限制,因为在numeric python所使用的数字处理程序中,能够对两个矩阵执行元素比较会更有用,返回一个包含每个元素的给定比较结果的矩阵。如果这两个矩阵的大小不同,那么比较必须能够引发异常以表明错误。

在python 2.1中,为了支持这种需求,添加了丰富的比较。现在,python类可以单独重载 <<=>>===!= 操作。新的神奇方法名称是:

操作

方法名称

<

__lt__()

<=

__le__()

>

__gt__()

>=

__ge__()

==

__eq__()

!=

__ne__()

(魔法方法以相应的fortran运算符命名 .LT. . .LE. ,&c.数字程序员几乎肯定非常熟悉这些名称,并且会发现它们很容易记住。)

这些神奇的方法都是这样的 method(self, other) 在哪里 self 将是操作员左侧的对象,而 other 将是右侧的对象。例如,表达式 A < B 将导致 A.__lt__(B) 被召唤。

这些神奇的方法中的每一个都可以返回任何东西:布尔值、矩阵、列表或任何其他Python对象。或者,如果比较不可能、不一致或无意义,它们也可以引发异常。

内置的 cmp(A,B) 函数可以使用丰富的比较机制,现在接受一个可选参数,指定要使用哪个比较操作;这是作为字符串之一给出的 "<""<="">"">=""==""!=" . 如果在没有可选第三个参数的情况下调用, cmp() 将只返回-1、0或+1,就像在以前的Python版本中一样;否则,它将调用适当的方法并可以返回任何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:警告框架

在过去的10年中,python积累了一定数量的过时模块和特性。很难知道什么时候可以安全地删除某个特性,因为没有办法知道有多少代码可以使用它——也许没有程序依赖于该特性,或者很多程序依赖于它。为了能够以更结构化的方式删除旧功能,添加了一个警告框架。当Python开发人员想要摆脱某个特性时,它首先会在下一个版本的Python中触发一个警告。接下来的python版本可以删除这个特性,用户将有一个完整的发布周期来删除旧特性的使用。

python 2.1添加了这个方案中要使用的警告框架。它增加了一个 warnings 提供发出警告和筛选不希望显示的警告的功能的模块。第三方模块也可以使用这个框架来否决他们不再希望支持的旧功能。

例如,在Python2.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__')

这将添加一个只应用于类警告的筛选器 DeprecationWarning 在中触发 __main__ 模块,并应用正则表达式以仅匹配有关 regex 模块被弃用,并将导致忽略此类警告。警告也只能打印一次,每次执行有问题的代码时都可以打印一次,或者转换为会导致程序停止的异常(当然,除非异常是以通常的方式捕获的)。

为了发出警告,还向Python的C API添加了函数;有关详细信息,请参阅PEP230或Python的API文档。

参见

PEP 5 -语言进化指南

由PaulPrescod编写,用于指定从Python中删除旧特性时要遵循的过程。本PEP中所述的政策尚未正式通过,但最终的政策可能不会与Prescod的建议有太大的不同。

PEP 230 -警告框架

由Guido van Rossum编写和实施。

PEP 229:新建系统

在编译python时,用户必须进入并编辑 Modules/Setup 文件以启用各种附加模块;默认设置相对较小,仅限于在大多数UNIX平台上编译的模块。这意味着在具有更多特性的Unix平台上,尤其是Linux上,python安装通常不包含所有有用的模块。

python 2.0添加了distutils,一组用于分发和安装扩展的模块。在python 2.1中,distuils用于编译许多扩展模块的标准库,自动检测当前机器上支持哪些扩展模块。希望这将使python的安装更容易、更具特色。

而不是必须编辑 Modules/Setup 文件以启用模块,a setup.py python源发行版顶部目录中的脚本在构建时运行,并尝试通过检查系统上的模块和头文件来发现可以启用哪些模块。如果模块配置在 Modules/Setup , the setup.py 脚本不会尝试编译该模块,并将遵从 Modules/Setup 文件内容。这提供了一种方法来指定特定平台所需的任何奇怪的命令行标志或库。

在构建机制的另一个影响深远的变化中,Neil Schemenauer重新构造了一些东西,因此python现在使用一个不是递归的makefile,而不是在顶部目录和每个 Python/Parser/Objects/Modules/ 子目录。这使得构建python的速度更快,也使得黑客攻击使文件更清晰、更简单。

参见

PEP 229 -使用distutils构建python

由A.M.Kuchling编写并实施。

PEP 205:弱引用

弱引用,可通过 weakref 模块,是Python程序员工具箱中一个次要但有用的新数据类型。

存储对某个对象的引用(例如,在字典或列表中)会产生使该对象永远保持活动状态的副作用。在一些特定的情况下,这种行为是不可取的,对象缓存是最常见的,而另一种情况是数据结构(如树)中的循环引用。

例如,考虑一个存储另一个函数结果的内存化函数 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 dictionary保存对返回值的引用,因此在Python进程退出并清除之前,它们永远不会被释放。对于整数来说这不是很明显,但是如果 f() 返回占用大量内存的对象或数据结构,这可能是一个问题。

弱引用提供了一种实现缓存的方法,该缓存不会使对象在超过其时间后保持活动。如果一个对象只能通过弱引用访问,那么该对象将被释放,弱引用现在将指示它引用的对象不再存在。对对象的弱引用 obj 是通过调用 wr = weakref.ref(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:功能属性

在Python2.1中,函数现在可以附加任意的信息。人们经常使用docstring来保存关于函数和方法的信息,因为 __doc__ 属性是将任何信息附加到函数的唯一方法。例如,在ZopeWeb应用程序服务器中,通过使用docstring将函数标记为对公共访问安全;在JohnAycock的spark解析框架中,docstring包含要解析的BNF语法的部分。这种重载是不幸的,因为docstring实际上是用来保存函数的文档的;例如,它意味着您不能正确地记录Zope中专用的函数。

现在可以使用常规的python语法在函数上设置和检索任意属性:

def f(): pass

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

包含属性的字典可以作为函数的 __dict__ . 不像 __dict__ 类实例的属性,在函数中,可以将新字典实际分配给 __dict__ 尽管新值仅限于常规的python字典;但是 不能 小心点,把它设为 UserDict 实例或任何其他类似于映射的随机对象。

参见

PEP 232 -函数属性

由巴里·华沙撰写并实施。

PEP 235:在不区分大小写的平台上导入模块

有些操作系统的文件系统不区分大小写,主要的例子是MacOS和Windows;在这些系统上,不可能区分文件名。 FILE.PYfile.py 即使它们确实将文件名存储在其原始大小写中(它们也保留大小写)。

在python 2.1中, import 语句将在不区分大小写的平台上模拟大小写敏感度。默认情况下,python现在将搜索第一个区分大小写的匹配,从而引发 ImportError 如果找不到这样的文件,那么 import file 不会导入名为的模块 FILE.PY . 通过设置 PYTHONCASEOK 启动python解释器之前的环境变量。

PEP 217:交互式显示挂钩

交互使用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 -交互式显示挂钩

由Moshe Zadka编写并实施。

PEP 208:新的强制模式

数值强制在C级的执行方式被显著修改。这只会影响python的C扩展的作者,允许他们在编写支持数值操作的扩展类型时更加灵活。

扩展类型现在可以设置类型标志 Py_TPFLAGS_CHECKTYPES 在他们 PyTypeObject 结构以指示它们支持新的强制模型。在这种扩展类型中,数字槽函数不能再假定将传递同一类型的两个参数;相反,可以传递不同类型的两个参数,然后可以执行自己的内部强制。如果向slot函数传递了它无法处理的类型,则可以通过返回对 Py_NotImplemented 单例值。然后将尝试其他类型的数值函数,也许它们可以处理该操作;如果其他类型也返回 Py_NotImplemented 然后 TypeError 将被引发。用python编写的数值方法也可以返回 Py_NotImplemented ,使解释器的行为好像该方法不存在(可能引发 TypeError ,可能尝试其他对象的数值方法)。

参见

PEP 208 -改造强制模式

由Neil Schemenauer撰写并实施,主要基于Marc Andr_Lemburg的早期工作。阅读本文了解现在如何在C级别处理数字操作的要点。

PEP 241:python包中的元数据

Python用户的一个常见抱怨是,现有的所有Python模块都没有一个目录。t.位于http://www.vex.net/parnassus/的Middleton的Parnassus金库是最大的python模块目录,但在金库注册软件是可选的,许多人不必费心。

作为解决问题的第一步,使用distutils打包的python软件 sdist 命令将包含名为 PKG-INFO 包含有关包的信息,例如包的名称、版本和作者(元数据,在编目术语中)。 PEP 241 包含可以出现在 PKG-INFO 文件。当人们开始使用python 2.1打包他们的软件时,越来越多的软件包将包含元数据,这使得构建自动编目系统和试验它们成为可能。根据结果经验,也许可以设计一个非常好的目录,然后在python 2.2中构建对它的支持。例如,distutils sdistbdist_* 命令可以支持 upload 自动将包上载到目录服务器的选项。

您可以开始创建包含 PKG-INFO 即使您没有使用python 2.1,因为distutils的新版本将为早期python版本的用户而发布。distutils的版本1.0.2包括中描述的更改 PEP 241 以及各种错误修复和增强。可从distuils sig获取,网址为https://www.python.org/community/sigs/current/distuils sig/。

参见

PEP 241 -python软件包的元数据

由A.M.Kuchling编写并实施。

PEP 243 -模块库上传机制

本文由SeanReifschneider编写,描述了一种将python包上传到中央服务器的提议机制。

新模块和改进模块

  • Ka Ping Yee贡献了两个新模块: inspect.py ,用于获取有关实时python代码的信息的模块,以及 pydoc.py ,用于交互地将文档字符串转换为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 很快就会上瘾,试试看!

  • 在标准库中添加了两个不同的单元测试模块。这个 doctest 模块由TimPeters提供,它提供了一个基于在DocStrings中运行嵌入式示例并将结果与预期输出进行比较的测试框架。PyUnit由StevePurcell提供,它是一个受JUnit启发的单元测试框架,JUnit又是对KentBeck的Smalltalk测试框架的改编。有关PYUnit的详细信息,请参阅http://pyunit.sourceforge.net/。

  • 这个 difflib 模块包含一个类, SequenceMatcher ,比较两个序列并计算将一个序列转换为另一个序列所需的更改。例如,此模块可用于编写类似于Unix的工具 diff 程序,实际上是示例程序 Tools/scripts/ndiff.py 演示如何编写这样的脚本。

  • curses.panel 是面板库的封装,是ncurses和sysv curses的一部分,由Thomas Gellekum提供。面板库为窗口提供了深度的附加功能。窗口可以按深度顺序上移或下移,面板库会找出面板重叠的位置以及哪些部分可见。

  • 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() ,需要一个浮点参数,该参数包含自epoch以来的时间(秒)。这些函数最常见的用途是使用当前时间,因此浮点参数被设置为可选;如果没有提供值,则使用当前时间。例如,日志文件条目通常需要一个包含当前时间的字符串;在python 2.1中, time.asctime() 可以使用,而不是长度 time.asctime(time.localtime(time.time())) 这是以前的要求。

    这一变化是由托马斯·沃特斯提出并实施的。

  • 这个 ftplib 模块现在默认为在被动模式下检索文件,因为被动模式更可能在防火墙后面工作。此请求来自Debian Bug跟踪系统,因为其他Debian包使用 ftplib 以检索文件,然后不从防火墙后面工作。这不太可能给任何人带来问题,因为Netscape默认为被动模式,很少有人抱怨,但如果被动模式不适合您的应用程序或网络设置,请致电 set_pasv(0) 在ftp对象上禁用被动模式。

  • 对原始套接字访问的支持已添加到 socket 模块,由Grant Edwards提供。

  • 这个 pstats 模块现在包含一个简单的交互式统计浏览器,用于显示Python程序的时间配置文件,当模块作为脚本运行时调用。埃里克·S·雷蒙德撰稿。

  • 一个新的依赖于实现的函数, sys._getframe([depth]) ,以从当前调用堆栈返回给定的帧对象。 sys._getframe() 返回调用堆栈顶部的框架;如果可选的integer参数 深度 如果提供,函数将返回 深度 在堆栈顶部以下调用。例如, sys._getframe(1) 返回调用方的帧对象。

    此函数只存在于cpython中,而不存在于jython或.NET实现中。使用它进行调试,并抵制将其放入生产代码的诱惑。

其他更改和修复

由于较短的发布周期,在python 2.1中进行的较小的更改相对较少。通过对cvs变更日志的搜索发现应用了117个补丁,修复了136个错误;这两个数字可能都被低估了。一些更显著的变化是:

  • 专用对象分配器现在是可选的,它应该比系统更快。 malloc() 并且内存开销更少。分配器使用C malloc() 函数获取大型内存池,然后满足来自这些池的较小内存请求。它可以通过提供 --with-pymalloc 选择权 configure 脚本;请参见 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%,在某些特定的操作系统上可能更快。TimPeters在comp.lang.python中进行了大量的基准测试和代码编写工作,这是由comp.lang.python中的讨论所推动的。

    还添加了一个新的文件对象模块和方法,由JeffEpler提供。新方法, 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() 删除随机项 (key, value) 从字典配对 D 以2元组的形式返回。这主要是由蒂姆·彼得斯和吉多·范·罗森实施的,在莫什·扎达卡提出建议并初步修补之后。

  • 模块现在可以控制在 from module import * 通过定义 __all__ 包含要导入的名称列表的属性。一个常见的抱怨是,如果模块导入其他模块,例如 sysstringfrom module import * 将它们添加到导入模块的命名空间中。要解决这个问题,只需在 __all__ ::

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

    BenWolfson首先提出并实现了更严格的补丁版本,但是在一些Python开发人员讨论之后,签入了一个更弱的最终版本。

  • 应用 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日志了解完整的详细信息。

确认

作者要感谢以下人士对本文的各种草稿提出了建议:格雷姆·克罗斯、大卫·古德、杰伊·格雷夫斯、迈克尔·哈德森、马克·安德尔·莱姆伯格、弗雷德里克·隆德、尼尔·舍曼纽尔、托马斯·沃特斯。