Python 2.1 的新增Function

  • Author

    • A.M. Kuchling

Introduction

本文介绍了 Python 2.1 中的新Function。尽管 2.1 中的变化不如 Python 2.0 中的变化多,但仍有一些令人惊喜的惊喜。 2.1 是第一个pass使用 Python 增强提案(PEP)进行指导的发行版,因此大多数可观的更改都随附有 PEP,这些 PEP 为更改提供了更完整的文档和设计依据。本文并非试图完整地记录新Function,而只是为 Python 程序员提供了新Function的概述。有关任何您特别感兴趣的新Function的更多详细信息,请参阅 Python 2.1 文档或特定的 PEP。

Python 开发团队的近期目标是加快新版本的发布速度,每 6 至 9 个月发布一次新版本。 2.1 是第一个以这种更快的速度发布的版本,第一个 alpha 版本出现在 1 月,也就是 2.0 finally版本发布三个月后。

Python 2.1 的finally版本于 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的代码中,通常可以pass将它们传递为参数的默认值来查找要复制的局部变量。

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

结果,以强大的Function风格编写的 Python 代码的可读性受到很大影响。

Python 2.1 的最重大更改是已将静态作用域添加到该语言中以解决此问题。首先,上面的示例中现在不需要name=name默认参数。简而言之,当给定的变量名称未在函数中分配值时(pass赋值,或defclassimport语句),将在封闭范围的本地名称空间中查找对该变量的引用。在 PEP 中可以找到有关规则的更详细说明以及实现的剖析。

此更改可能会导致代码的某些兼容性问题,在该代码中,在模块级别和用作包含更多函数定义的函数中的局部变量都使用相同的变量名。不过,这似乎不太可能,因为这样的代码最初阅读起来会很混乱。

更改的一个副作用是,在某些情况下,from module import *exec语句在函数范围内已变为非法。 Python 参考手册一直说from module import *仅在模块的顶层是合法的,但是 CPython 解释器以前从未执行过此操作。作为实现嵌套作用域的一部分,将 Python 源代码转换为字节码的编译器必须生成不同的代码以访问包含作用域中的变量。 from module import *exec使编译器无法弄清楚这一点,因为它们将名称添加到了在编译时无法得知的本地名称空间。因此,如果函数包含带有自由变量的函数定义或lambda表达式,则编译器将pass引发SyntaxError异常来进行标记。

为了使前面的解释更加清楚,下面是一个示例:

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

包含exec语句的第 4 行是语法错误,因为exec将定义一个名为x的新局部变量,其值应由g()访问。

这应该不是很大的限制,因为在大多数 Python 代码中很少使用exec(并且当使用exec时,无论如何它通常都是不良设计的标志)。

兼容性问题导致嵌套作用域逐渐被引入。在 Python 2.1 中,默认情况下未启用它们,但是可以使用 PEP 236 中所述的 future 语句在模块中将其打开。(有关 PEP 236 的进一步讨论,请参见以下部分.)在 Python 2.2 中,嵌套作用域将成为默认值,并且无法关闭它们,但是用户将拥有 2.1 的整个生命周期来修复由于其引入而导致的任何损坏。

See also

  • PEP 227-静态嵌套范围

  • 由 Jeremy Hylton 编写并实施。

PEP 236:__ future_指令

对嵌套作用域的反应引起了人们广泛的关注,担心在 2.1 版本中破坏代码的危险,并且这种作用足以使 Pythoneers 采取更为保守的方法。此方法包括引入一个约定,以在版本 N 中启用可选Function,而在版本 N 1 中将启用该Function。

该语法使用保留模块名futurefrom...import语句。可以pass以下语句启用嵌套作用域:

from __future__ import nested_scopes

它看起来像普通的import语句,但不是;对于将来的语句可以放置在哪里有严格的规定。它们只能位于模块的顶部,并且必须在任何 Python 代码或常规import语句之前。这是因为此类语句可能会影响 Python 字节码编译器解析代码和生成字节码的方式,因此它们必须位于将导致生成字节码的任何语句之前。

See also

  • PEP 236-返回future

  • 由 Tim Peters 撰写,主要由 Jeremy Hylton 实施。

PEP 207:丰富的比较

在早期版本中,Python 支持在用户定义的类和扩展类型上实现比较,这非常简单。类可以实现给一个类的两个实例的cmp()方法,并且如果它们相等则只能返回 0,否则就返回 1 或-1.该方法无法引发异常或返回布尔值以外的任何内容。使用 Numeric Python 的用户经常会发现此模型过于脆弱和局限,因为在使用 Python 数字化的数字运算程序中,能够对两个矩阵进行元素比较会更有用,返回包含结果的矩阵。每个元素的给定比较。如果两个矩阵的大小不同,则比较必须能够引发异常以发出错误 signal。

在 Python 2.1 中,添加了丰富的比较以支持此需求。 Python 类现在可以分别重载<<=>>===!=操作。新的魔术方法名称为:

OperationMethod name
<lt()
<=le()
>gt()
>=ge()
==eq()
!=ne()

(魔术方法以相应的 Fortran 运算符.LT..LE.和&c 命名.数值程序员几乎可以肯定对这些名称非常熟悉,并且会发现它们易于 Memory.)

这些魔术方法均采用method(self, other)的形式,其中self是运算符左侧的对象,而other是右侧运算符的对象。例如,表达式A < B将导致A.__lt__(B)被调用。

这些魔术方法中的每一个都可以返回任何东西:布尔值,矩阵,列表或任何其他 Python 对象。或者,如果比较不可能,不一致或无意义,他们可以提出 exception。

内置的cmp(A,B)函数可以使用丰富的比较机制,并且现在接受一个可选参数,用于指定要使用的比较操作;它以字符串"<""<="">"">=""==""!="之一给出。如果在没有可选的第三个参数的情况下调用cmp(),则只会返回 python 先前版本中的-1、0 或 1.否则它将调用适当的方法,并可以返回任何 Python 对象。

C 程序员也有相应的兴趣爱好变化;类型对象中有一个新的插槽tp_richcmp,以及用于执行给定丰富比较的 API。我不会在这里介绍 C API,但会为您提供 PEP 207 或 2.1 的 C API 文档,以获取相关Function的完整列表。

See also

  • PEP 207-丰富的比较

  • 由 Guido van Rossum 撰写,主要基于 David Ascher 的早期工作,并由 Guido van Rossum 实施。

PEP 230:警告框架

在成立的 10 年中,Python 沿途积累了一定数量的过时模块和Function。很难知道何时可以安全删除某个Function,因为无法知道有多少代码使用了该Function-也许没有程序依赖于该Function,或者也许很多程序都依赖该Function。为了能够以更结构化的方式删除旧Function,添加了警告框架。当 Python 开发人员想要摆脱某个Function时,它将首先在下一个 Python 版本中触发警告。然后,以下 Python 版本可以删除该Function,并且用户将具有完整的发布周期以删除对旧Function的使用。

Python 2.1 添加了用于此方案的警告框架。它添加了一个warnings模块,该模块提供了发出警告以及过滤出不想显示的警告的Function。第三方模块也可以使用此框架来淘汰不再希望支持的旧Function。

例如,在 Python 2.1 中不建议使用regex模块,因此导入该模块会导致显示警告:

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

可以pass调用warnings.warn()函数发出警告:

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

第一个参数是警告消息。其他可选参数可用于指定特定的警告类别。

可以添加过滤器以禁用某些警告。可以将正则表达式模式应用于消息或模块名称,以禁止显示警告。例如,您可能有一个使用regex模块的程序,并且不想浪费时间将其转换为现在使用re模块。可以pass调用来禁止警告

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 文档。

See also

  • PEP 5-语言进化准则

  • Paul Prescod 撰写,指定了从 Python 删除旧Function时要遵循的过程。该 PEP 中描述的策略尚未正式采用,但finally的策略与 Prescod 的提议可能并没有太大不同。

  • PEP 230-警告框架

  • 由 Guido van Rossum 编写和实施。

PEP 229:新构建系统

编译 Python 时,用户必须进入并编辑Modules/Setup文件才能启用各种其他模块。默认设置相对较小,并且仅限于在大多数 Unix 平台上编译的模块。这意味着在具有更多Function的 Unix 平台上,最著名的是 Linux,Python 安装通常不会包含它们可能会使用的所有有用模块。

Python 2.0 添加了 Distutils,Distutils 是一组用于分发和安装扩展的模块。在 Python 2.1 中,Distutils 用于编译许多扩展模块标准库,自动检测当前计算机上支持哪些扩展模块。希望这将使 Python 的安装更加容易并且Function更多。

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

在对构建机制进行的又一项意义深远的更改中,尼尔·斯德瑙尔(Neil Schemenauer)进行了重组,因此 Python 现在使用的是一个非递归的生成文件,而不是顶层目录以及Python/Parser/Objects/Modules/子目录中的每个 makefile。这使构建 Python 的速度更快,也使对 Makefile 的黑客攻击更加清晰和简单。

See also

  • PEP 229-使用 Distutils 构建 Python

  • 由 A.M.撰写并实施 Kuchling。

PEP 205:参考文献不足

passweakref模块可用的弱引用是 Python 程序员工具箱中的次要但有用的新数据类型。

存储对对象的引用(例如,在字典或列表中)具有使该对象永远存活的副作用。在某些特定情况下,这种行为是不希望的,对象缓存是最常见的一种,而另一种则是数据结构(例如树)中的循环引用。

例如,考虑一个 Memory Function,该Functionpass将函数的参数及其结果存储在字典中来缓存另一个函数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()返回一个对象,或者数据结构占用了一个很多内存,这可能是一个问题。

弱引用提供了一种实现高速缓存的方法,该高速缓存不会使对象存活超过其时间。如果只能pass弱引用访问对象,则该对象将被释放,并且弱引用现在将指示该对象不再存在。pass调用wr = weakref.ref(obj)创建对对象* obj *的弱引用。pass调用弱引用来返回被引用的对象,就像它是一个函数wr()一样。它将返回引用的对象,如果对象不存在,则返回None

pass在缓存中存储弱引用,可以编写一个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模块还允许创建行为类似于弱引用的代理对象-仅释放由代理对象引用的对象-但不需要显式调用来检索该对象,只要该对象透明地将所有操作转发给该对象仍然存在。如果对象被释放,则try使用代理将引发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

See also

  • PEP 205-Weak References

  • 由 Fred L. Drake,Jr.撰写并实施

PEP 232:Function属性

在 Python 2.1 中,函数现在可以附加任意信息。人们经常使用文档字符串来保存有关函数和方法的信息,因为__doc__属性是将任何信息附加到函数的唯一方法。例如,在 Zope Web 应用程序服务器中,pass具有文档字符串将Function标记为对于公共访问是安全的,并且在 John Aycock 的 SPARK 解析框架中,文档字符串包含要解析的 BNF 语法的一部分。这种重载是不幸的,因为文档字符串实际上是用来保存函数文档的。例如,这意味着您不能正确记录 Zope 中供私人使用的Function。

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

def f(): pass

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

包含属性的字典可以作为函数的dict进行访问。与类实例的dict属性不同,在函数中您实际上可以为dict分配新字典,尽管新值仅限于常规 Python 字典;您不能棘手,将其设置为UserDict实例,或其他行为类似于 Map 的随机对象。

See also

  • PEP 232-函数属性

  • 由 Barry Warsaw 编写并实施。

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

某些 os 的文件系统不区分大小写,主要的示例是 MacOS 和 Windows。在这些系统上,即使它们确实以原始大小写存储文件名(它们也保持大小写),都无法区分文件名FILE.PYfile.py

在 Python 2.1 中,import语句将在不区分大小写的平台上模拟大小写敏感度。现在,Python 默认会搜索第一个区分大小写的匹配项,如果找不到此类文件,则会引发ImportError,因此import file将不会导入名为FILE.PY的模块。在启动 Python 解释器之前,可以pass设置 PYTHONCASEOK环境变量来请求不区分大小写的匹配。

PEP 217:互动式展示钩子

交互使用 Python 解释器时,将使用内置的repr()函数显示命令的输出。在 Python 2.1 中,可以将变量sys.displayhook()设置为可调用对象,而不是repr()将被调用。例如,您可以将其设置为特殊的漂亮打印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>]
>>>

See also

  • PEP 217-显示钩子以供互动使用

  • 由 Moshe Zadka 编写并实施。

PEP 208:新的强制模式

显着修改了如何在 C 级别执行数字强制。这只会影响 C 语言对 Python 扩展的作者,从而使他们在编写支持数字运算的扩展类型时更具灵 Active。

扩展类型现在可以在其PyTypeObject结构中设置类型标志Py_TPFLAGS_CHECKTYPES,以指示它们支持新的强制模型。在这样的扩展类型中,数字槽函数不能再假定它们将被传递给两个相同类型的参数。相反,它们可以传递两个不同类型的参数,然后可以执行自己的内部强制。如果将插槽函数传递给它无法处理的类型,则可以pass返回对Py_NotImplemented单例值的引用来指示失败。然后将try其他类型的数字函数,也许它们可以处理该操作。如果另一个类型也返回Py_NotImplemented,则将引发TypeError。用 Python 编写的数字方法也可以返回Py_NotImplemented,从而使解释器以该方法不存在的方式运行(也许引发TypeError,也许try使用另一个对象的数字方法)。

See also

  • PEP 208-重制强制模型

  • 由 Neil Schemenauer 撰写和实施,很大程度上是基于 Marc-AndréLemburg 的早期工作。阅读本文以了解如何在 C 级别处理数字运算的要点。

PEP 241:Python 软件包中的元数据

Python 用户的一个普遍抱怨是,不存在所有 Python 模块的单一目录。 T. Middleton 在http://www.vex.net/parnassus/的 Parnassus 的 Vaults 是最大的 Python 模块目录,但是在 Vaults 中注册软件是可选的,而且很多人都不会打扰。

作为解决此问题的第一步,使用 Distutils sdist 命令打包的 Python 软件将包含一个名为PKG-INFO的文件,其中包含有关该软件包的信息,例如其名称,版本和作者(在分类术语中为元数据)。 PEP 241 包含PKG-INFO文件中可能存在的字段的完整列表。随着人们开始使用 Python 2.1 打包软件,越来越多的软件包将包含元数据,从而可以构建自动编目系统并对其进行试验。有了结果经验,也许可以设计出一个非常好的目录,然后将其支持到 Python 2.2 中。例如,Distutils 的 sdistbdist _ *命令可以支持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/获得。

See also

  • PEP 241-Python 软件包的元数据

  • 由 A.M.撰写并实施 Kuchling。

  • PEP 243-模块存储库上传机制

  • 该 PEP 草案由 Sean Reifschneider 撰写,描述了一种用于将 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很快会上瘾;试试看!

  • 将两个用于单元测试的不同模块添加到标准库中。蒂姆·彼得斯(Tim Peters)贡献的doctest模块提供了一个测试框架,该框架基于在文档字符串中运行嵌入式示例并将结果与预期输出进行比较。由 Steve Purcell 贡献的 PyUnit 是一个受 JUnit 启发的单元测试框架,而 JUnit 则是 Kent Beck 的 Smalltalk 测试框架的改编。有关 PyUnit 的更多信息,请参见http://pyunit.sourceforge.net/

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

  • curses.panel是面板库的包装,是 ncurses 和 SYSV curses 的一部分,由 Thomas Gellekum 贡献。面板库为窗口提供了附加的深度Function。可以按深度 Sequences 将窗口向上或向下移动,面板库会找出面板重叠的位置以及可见的部分。

  • 自 Python 2.0 以来,PyXML 软件包已经经历了几个版本,而 Python 2.1 包括了xml软件包的更新版本。一些值得注意的更改包括对 Expat 1.2 和更高版本的支持,Expat 解析器处理 Python 支持的任何编码的文件的Function以及 SAX,DOM 和minidom模块的各种错误修正。

  • Ping 还提供了另一个钩子来处理未捕获的异常。 sys.excepthook()可以设置为可调用对象。当任何tryexcept块都未捕获到异常时,该异常将被传递给sys.excepthook(),然后sys.excepthook()可以做任何喜欢的事情。在第九届 Python 大会上,Ping 演示了此钩子的应用程序:打印扩展的 traceback,该 traceback 不仅列出堆栈框架,而且列出每个框架的函数参数和局部变量。

  • time模块中的各种Function(例如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 ,则该函数返回在堆栈顶部下方调用 depth *的帧。例如,sys._getframe(1)返回调用方的框架对象。

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

其他更改和修复

由于发布周期较短,在 Python 2.1 中进行的较小更改相对较少。在 CVS 变更日志中进行搜索可以找到 117 个补丁,并修复了 136 个错误。这两个数字都可能被低估了。一些更显着的变化是:

  • 现在可以选择使用专门的对象分配器,该对象分配器应该比系统malloc()更快,并且具有较少的内存开销。分配器使用 C 的malloc()函数获取较大的内存池,然后从这些池执行较小的内存请求。可以pass在 configure 脚本中提供--with-pymalloc选项来启用它。有关实现的详细信息,请参见Objects/obmalloc.c

C 扩展模块的作者应在启用对象分配器的情况下测试其代码,因为某些不正确的代码可能会break,从而在运行时导致核心转储。 Python 的 C API 中有一堆内存分配函数,这些函数以前只是 C 库的malloc()free()的别名,这意味着如果您不小心调用了不匹配的函数,该错误将不会引起注意。启用对象分配器后,这些函数不再是malloc()free()的别名,并且调用错误的函数释放内存将获得核心转储。例如,如果使用PyMem_New()分配内存,则必须使用PyMem_Del()而不是free()释放内存。 Python 附带的一些模块与此不符,必须加以修复;毫无疑问,会有更多的第三方模块会出现相同的问题。

对象分配器由 Vladimir Marangozov 贡献。

  • 面向行的文件 I/O 的速度得到了提高,因为人们经常抱怨它缺乏速度,并且因为它经常被用作幼稚的基准。因此,文件对象的readline()方法已被重写为更快。确切的加速量因平台而异,具体取决于 C 库getc()的运行速度,但约为 66%,在某些特定的 os 上可能要快得多。蒂姆·彼得斯(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 日在https://mail.python.org/pipermail/python-dev/2001-January/处的 python-dev 摘要。

  • 在字典中添加了一种新方法popitem(),从而可以破坏性地遍历字典的内容。对于大型词典,这可能会更快,因为无需构造包含所有键或值的列表。 D.popitem()从字典D中删除一个随机的(key, value)对,并将其作为 2Tuples 返回。在 Moshe Zadka 的建议和初步修补后,这主要由 Tim Peters 和 Guido van Rossum 实施。

  • 现在,模块可以pass定义__all__属性(包含将要导入的名称列表)来控制使用from module import *时要导入的名称。一个普遍的抱怨是,如果模块导入其他模块,例如sysstring,则from module import *会将它们添加到导入模块的名称空间中。要解决此问题,只需在__all__中列出公共名称:

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

Ben Wolfson 首次提出并实现了此补丁的更严格版本,但是在进行一些 python-dev 讨论后,检查了一个较弱的finally版本。

  • repr()应用于以前使用的八进制转义符来表示不可打印的字符;例如,换行符是'\012'。这是 Python C 祖先的遗迹,但今天八进制几乎没有实际用途。叶家平建议使用十六进制转义符而不是八进制转义符,并对适当的字符使用\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)。

还有一些常见的次要错误修复,次要内存泄漏,文档字符串编辑和其他调整的列表,它们太长了,不值得逐项列出;如果需要,请参阅 CVS 日志以获取完整详细信息。

Acknowledgements

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