# Python 2.6 有什么新变化

作者:

  A.M. Kuchling (amk at amk.ca)

本文介绍了 Python 2.6 的新特性，它发布于 2008 年 10 月 1 日。发布日程说明见 PEP 361。

Python 2.6 的重要主题是准备好迁移到 Python 3.0，该版本是这个编程语言的一次重大重新设计。 只要有可能，Python 2.6 就会纳入来自 3.0 的新特性和语法同时通过不移除旧特性或语法来保持与现有代码的兼容。 当无法做到这一点时，Python 2.6 会尽力而为，在 `future_builtins` 模块中添加兼容性函数并用 `-3` 开关来警告将在 3.0 变得不受支持的用法。

标准库中增加了一些重要的新包，如 `multiprocessing` 和 `json` 模块等，但与 Python 3.0 完全无关联的新特性并不多。

Python 2.6 还对整个源代码进行了大量改进和错误修复。 通过搜索更改日志我们发现在 Python 2.5 和 2.6 之间应用了 259 个补丁并修复了 612 个错误。 这两个数字可能都被低估了。

本文并不试图提供新特性的完整规范说明，而是提供一个方便的概览。 要了解完整的细节，请参阅 Python 2.6 的文档。 如果你想了解有关设计和实现的具体考量，请参阅特定新特性 的 PEP。 在可能的情况下，“Python 有什么新变化”为每个更改的错误修正/补丁项提供链接。

## Python 3.0

Python版本2.6和3.0的开发周期是同步的，两个版本的alpha和beta版本是在同一天发布的。3.0的发展影响了2.6中的许多功能。

Python 3.0 是对 Python 的大范围重新设计，打破了与 2.x 系列的兼容性。 这意味着现有的 Python 代码需要进行一些转换才能在 Python 3.0 上运行。 不过，并非 3.0 中的所有更改都会破坏兼容性。 在新特性不会导致现有代码崩溃的情况下，它们会被回溯到 2.6，并在本文档的适当位置进行描述。 部分 3.0 衍生功能包括:

- 用于将对象转换为复数的 `__complex__()` 方法。

- 用于捕获异常的替代语法: `except TypeError as exc`。

- 增加 `functools.reduce()` 作为内置 `reduce()` 函数的同义词。

Python 3.0 新增了一些内置函数并对部分现有内置函数的语法进行了修改。 在 3.0 中新增的函数如 `bin()` 已直接添加到 Python 2.6 中，但现有的内置函数则未做修改；作为替代，在 `future_builtins` 模块中包含了使用新的 3.0 语义的版本。 要编写与 3.0 兼容的代码可以在必要时执行 `from future_builtins import hex, map`。

新增的命令行开关 `-3` 将启用对将在 Python 3.0 中移除的特性的警告。 你可以使用该开关运行代码以了解将代码移植到 3.0 需要做多少工作。 Python 代码可以使用布尔型变量 `sys.py3kwarning` 访问该开关的值，对于 C 扩展代码则可以使用 `Py_Py3kWarningFlag`。

参见

3xxx 系列 PEP 包含针对 Python 3.0 的提议。 PEP 3000 描述了 Python 3.0 的开发进程。 从 PEP 3100 开始描述 Python 3.0 的主要目标，然后继续列出提议具体特性的更高数字的 PEP。

## 开发过程的变化

在开发2.6时，Python开发过程经历了两个重大变化：我们从SourceForge的问题跟踪程序切换到定制的Roundup安装，文档从LaTeX转换为reStructuredText。

### 新问题追踪：简述

很长一段时间以来，Python开发人员对SourceForge的bug跟踪器越来越恼火。SourceForge的托管解决方案不允许进行大量定制；例如，无法定制问题的生命周期。

Python软件基金会的基础设施委员会因此发布了一个问题跟踪器的征集公告，邀请志愿者设置不同的产品，并从SourceForge导入一些错误和补丁。评估了四种不同的跟踪器：Jira，Launchpad，Roundup <https://roundup.sourceforge.io/>`__和`Trac。委员会最终确定Jira和Roundup为两个候选方案。Jira是一个商业产品，为自由软件项目提供免费托管实例；Roundup是一个开源项目，需要志愿者来管理，并需要一个服务器来托管。

在发出志愿者号召后，在https://bugs.python.org的一个Roundup的安装可以托管多个跟踪器，现在该服务器还托管Jython和Python网站的问题跟踪器。它肯定会在未来找到其他用途。在可能的情况下，此版本的“What's New in Python”链接到每个更改的bug/补丁项。

Python错误跟踪器的托管由南非斯泰伦博斯市的 Upfront Systems 友好提供。Martin von Löwis 在从 SourceForge 导入现有错误和补丁方面做了大量工作；他的导入脚本位于 `https://svn.python.org/view/tracker/importer/`，对于希望从 SourceForge 迁移到 Roundup 的其他项目可能有所帮助。

参见

https://bugs.python.org

  Python 的错误追踪器。

https://bugs.jython.org:

  Jython 的错误追踪器。

https://roundup.sourceforge.io/

  Roundup 下载和文档。

https://svn.python.org/view/tracker/importer/

  Martin von Löwis 的转换脚本。

### 新的文档格式：使用 Sphinx 的 reStructuredText

自 1989 年左右项目启动以来，Python 文档一直使用 LaTeX 编写。在 1980 年代和 1990 年代早期，大多数文档都是打印出来供日后学习的，而不是在网上查看。 LaTeX 被广泛使用，因为它既能提供美观的打印输出，又能在掌握了标记的基本规则后直接进行编写。

如今 LaTeX 仍被用于编写印刷出版物，但编程工具的格局已经发生了变化。 我们不再打印成堆的文档，取而代之的是在线浏览，HTML 已成为最重要的支持格式。 不幸的是，将 LaTeX 转换为 HTML 相当复杂，长期担任 Python 文档编辑的 Fred L. Drake Jr. 花了许多时间在维护转换过程上。 偶尔有人会建议将文档转换成 SGML，之后再转换成 XML，但进行良好的转换是一项艰巨的任务，从来没有人投入所需的时间来完成这项工作。

在 2.6 开发周期中，Georg Brandl 投入了大量精力来构建一个新的工具链，用于处理文档。由此产生的软件包名为 Sphinx，可从 https://www.sphinx-doc.org/ 获取。

Sphinx 专注于 HTML 输出，可生成吸引人风格的现代 HTML；通过转换为 LaTeX，仍可支持打印输出。输入格式是 reStructuredText，这是一种支持自定义扩展和指令的标记语法，在 Python 社区很常用。

Sphinx 是一个可用于写文档的独立软件包，将近二十多个其他项目 (列在 Sphinx 网站 上) 已采用 Sphinx 作为其文档工具。

参见

Documenting Python

  描述如何编写Python文档。

Sphinx

  Sphinx工具链的文档和代码。

Docutils

  reStructuredText 的基础解析器和工具集。

## PEP 343: "with" 语句

在 Python 2.5 之前的版本中，"`with`" 语句是一个可选功能，可以通过 `from __future__ import with_statement` 指令启用。 在 2.6 中，该语句不再需要特别启用；这意味着 `with` 现在总是一个关键字。 本节的其余部分是“Python 2.5 新特性”文档中相应部分的复制；如果你熟悉 Python 2.5 中的 '`with`' 语句，可以跳过本节。

'`with`' 语句澄清了以前使用 `try...finally` 块来确保执行清理代码的代码。在本节中，我将讨论该语句的常见用法。在下一节中，我将探讨实现细节，并展示如何编写与该语句一起使用的对象。

'`with`' 语句是一种基本结构如下所示的流程控制结构:

    with expression [as variable]:
        with-block

表达式会被求值，并且其结果应为一个支持上下文协议的对象（即具有 `__enter__()` 和 `__exit__()` 方法）。

在执行 with-block 之前，会调用对象的 `__enter__()` 方法，因此可以运行设置代码。它还可以返回一个值，该值绑定到 variable*（如果给出的话）。（请注意，*variable 并不是被赋值为 expression 的结果。）

在 with-block 执行完成后，即使块引发了异常，也会调用对象的 `__exit__()` 方法，因此可以运行清理代码。

一些标准 Python 对象现在已支持上下文管理协议并可被用于 '`with`' 语句。 文件对象就是一个例子:

    with open('/etc/passwd', 'r') as f:
        for line in f:
            print line
            ... 更多处理代码 ...

在此语句被执行之后，文件对象 f 将被自动关闭，即使是当 `for` 循环在代码块中间引发了异常的时候也是如此。

备注

在此情况下，f 就是由 `open()` 所创建的对象，因为 `__enter__()` 会返回 self。

`threading` 模块的加锁和条件变量也支持 '`with`' 语句:

    lock = threading.Lock()
    with lock:
        # 关键代码段
        ...

这个锁会在代码块被执行之前锁定并总是会在代码块完成之后释放。

`decimal` 模块的 `localcontext()` 函数使得保存和恢复当前的十进制数上下文更为容易，它封装了计算所要使用的精度和舍入方式:

    from decimal import Decimal, Context, localcontext

    # 使用默认精度 28 位显示
    v = Decimal('578')
    print v.sqrt()

    with localcontext(Context(prec=16)):
        # 此代码块中的所有代码使用 16 位精度。
        # 退出代码块时恢复原始上下文。
        print v.sqrt()

### 编写上下文管理器

在底层，'`with`' 语句相当复杂。大多数人只会与现有对象一起使用 '`with`'，不需要了解这些细节，所以如果你愿意，可以跳过本节的其余部分。新对象的作者需要理解底层实现的细节，应该继续阅读。

在更高层级上对于上下文管理器协议的解释:

- 表达式被评估，并应生成一个称为“上下文管理器”的对象。上下文管理器必须具有 `__enter__()` 和 `__exit__()` 方法。

- 调用上下文管理器的 `__enter__()` 方法。返回的值被赋给 VAR。如果没有 `as VAR` 子句，该值将被丢弃。

- BLOCK 中的代码会被执行。

- 如果 BLOCK 引发异常，将使用三个参数调用上下文管理器的 `__exit__()` 方法，即异常详情（`type, value, traceback`，与 `sys.exc_info()` 返回的值相同，如果没有发生异常，这些值也可以是 `None`）。该方法的返回值控制是否重新引发异常：任何假值将重新引发异常，而 `True` 将导致抑制异常。你很少会想抑制异常，因为如果你这样做，包含 '`with`' 语句的代码作者将永远不会意识到出了问题。

- 如果 BLOCK 没有引发异常，仍然会调用 `__exit__()` 方法，但 type、value 和 traceback 都是 `None`。

让我们通过一个例子来思考。我不会展示详细的代码，而只会概述支持事务的数据库所需的方法。

（对于不熟悉数据库术语的人来说：对数据库的一组更改被组合成一个事务。事务可以被提交，意味着所有更改都被写入数据库，或者被回滚，意味着所有更改都被丢弃，数据库保持不变。更多信息请参阅任何数据库教材。）

假设有一个表示数据库连接的对象。我们的目标将允许用户编写如下代码：

    db_connection = DatabaseConnection()
    with db_connection as cursor:
        cursor.execute('insert into ...')
        cursor.execute('delete from ...')
        # ... 更多操作 ...

如果块中的代码能完美运行则应当提交事务而如果出现异常则应当回滚。 以下是我假设的 `DatabaseConnection` 基本接口:

    class DatabaseConnection:
        # 数据库接口
        def cursor(self):
            "返回一个游标对象并开始一个新事务"
        def commit(self):
            "提交当前事务"
        def rollback(self):
            "回滚当前事务"

`__enter__()` 方法非常简单，只需开始一个新事务。对于此应用程序，生成的游标对象将是一个有用的结果，因此该方法将返回它。用户可以在他们的 '`with`' 语句中添加 `as cursor` 来将游标绑定到一个变量名。：

    class DatabaseConnection:
        ...
        def __enter__(self):
            # 开始新事务的代码
            cursor = self.cursor()
            return cursor

`__exit__()` 方法是最复杂的，因为大部分工作都要在这里完成。该方法需要检查是否发生了异常。如果没有异常，事务被提交。如果发生了异常，事务被回滚。

在下面的代码中，执行将直接从函数末尾跳出，返回默认值 `None`。`None` 为假值，因此异常将自动重新抛出。如果你希望更明确，可以在标记的位置添加一个 `return` 语句。:

    class DatabaseConnection:
        ...
        def __exit__(self, type, value, tb):
            if tb is None:
                # 没有异常，因此提交
                self.commit()
            else:
                # 发生异常，因此回滚。
                self.rollback()
                # 返回 False

### contextlib 模块

`contextlib` 模块提供了一些函数和一个装饰器，这些在编写用于与'`with`'语句一起使用的对象时非常有用。

该装饰器名为 `contextmanager()`，它让你能编写单独的生成器函数而不是定义一个新类。 生成器应当产生恰好一个值。 到 `yield` 为止的代码将作为 `__enter__()` 方法执行，而产生的值将作为该方法的返回值被绑定到 '`with`' 语句的 `as` 子句中的变量，如果有的话。 在 `yield` 之后的代码将在 `__exit__()` 方法中被执行。 在代码块中引发的任何异常都将由 `yield` 语句引发。

使用这个装饰器，我们上一节中的数据库示例可以写成:

    from contextlib import contextmanager

    @contextmanager
    def db_transaction(connection):
        cursor = connection.cursor()
        try:
            yield cursor
        except:
            connection.rollback()
            raise
        else:
            connection.commit()

    db = DatabaseConnection()
    with db_transaction(db) as cursor:
        ...

`contextlib` 模块还有一个``nested(mgr1, mgr2, ...)``函数，它可以将多个上下文管理器组合在一起，这样你就不需要编写嵌套的'`with`'语句。在这个例子中，单个'`with`'语句既启动数据库事务又获取线程锁:

    lock = threading.Lock()
    with nested (db_transaction(db), lock) as (cursor, locked):
        ...

最后，`closing()` 函数返回其参数以便它可被绑定到变量，并在代码块结束时调用参数的 `.close()` 方法。

    import urllib, sys
    from contextlib import closing

    with closing(urllib.urlopen('http://www.yahoo.com')) as f:
        for line in f:
            sys.stdout.write(line)

参见

PEP 343 - "with" 语句

  PEP由Guido van Rossum和Nick Coghlan撰写；由Mike Bland、Guido van Rossum和Neal Norwitz实现。PEP展示了为'`with`'语句生成的代码，这对于学习该语句的工作原理很有帮助。

`contextlib` 模块的文档。

## PEP 366: 从主模块显式相对导入

Python 的 `-m` 开关允许将一个模块作为脚本来运行。 当你运行一个位于某个包内的模块时，相对导入将无法正确运作。

Python 2.6的修复增加了一个 `module.__package__` 属性。当此属性存在时，相对导入将相对于此属性的值而不是 `__name__` 属性。

PEP 302风格的导入器可以按需设置 `__package__`。实现 `-m` 开关的 `runpy` 模块现在就这样做，因此相对导入现在可以在从包内运行的脚本中正确工作。

## PEP 370: 分用户的 site-packages 目录

当你运行Python时，模块搜索路径 `sys.path` 通常包括一个路径以 `"site-packages"` 结尾的目录。这个目录旨在存放本地安装的、对所有使用该机器或特定站点安装的用户可用的包。

Python 2.6 引入了一个用于用户专属站点目录的惯例。 该目录根据具体系统平台各不相同:

- Unix 和 Mac OS X: `~/.local/`

- Windows: `%APPDATA%/Python`

在此目录中，会有特定版本的子目录，例如在Unix/Mac OS上的 `lib/python2.6/site-packages` 和在Windows上的 `Python26/site-packages`。

如果你不喜欢默认的目录，可以通过环境变量来覆盖它。 `PYTHONUSERBASE` 设置支持此特性的所有 Python 版本所使用的根目录。 在 Windows 上，应用程序专属数据的目录可通过设置 `APPDATA` 环境变量来更改。 你也可以针对你的 Python 安装版修改 `site.py` 文件。

此功能可以通过使用 `-s` 选项运行Python或设置 `PYTHONNOUSERSITE` 环境变量来完全禁用。

参见

PEP 370 - 分用户的 site-packages 目录

  PEP 由 Christian Heimes 撰写并实现。

## PEP 371: `multiprocessing` (多进程)包

新的 `multiprocessing` 包让Python程序可以创建新进程来执行计算并返回结果给父进程。父进程和子进程可以使用队列和管道进行通信，使用锁和信号量同步它们的操作，并且可以共享简单的数据数组。

The `multiprocessing` 模块起初是作为 `threading` 模块的精确模拟，使用进程而不是线程。 这个目标在 Python 2.6 的开发过程中被放弃了，但模块的总体思路仍然是类似的。 基础的类是 `Process`，它接受一个可调用对象和一组参数。 `start()` 方法将设置在一个子进程中运行的可调用对象，之后你可以调用 `is_alive()` 方法来检查子进程是否仍在运行并调用 `join()` 方法来等待进程退出。

下面是一个简单的示例，子进程将计算阶乘。执行计算的函数写得很奇怪，以便当输入参数是 4 的倍数时，它会花费更长的时间。

    import time
    from multiprocessing import Process, Queue

    def factorial(queue, N):
        "计算阶乘"
        # 如果 N 是 4 的倍数，这个函数将会花费更长的时间。
        if (N % 4) == 0:
            time.sleep(.05 * N/4)

        # 计算结果
        fact = 1L
        for i in range(1, N+1):
            fact = fact * i

        # 将结果放入队列
        queue.put(fact)

    if __name__ == '__main__':
        queue = Queue()

        N = 5

        p = Process(target=factorial, args=(queue, N))
        p.start()
        p.join()

        result = queue.get()
        print 'Factorial', N, '=', result

使用 `Queue` 来传递阶乘的结果。`Queue` 对象存储在一个全局变量中。子进程将使用创建子进程时的变量值；因为它是 `Queue`，父进程和子进程可以使用该对象进行通信。（如果父进程更改全局变量的值，子进程的值不会受影响，反之亦然。）

另外两个类，`Pool` 和 `Manager`，提供更高层级的接口。 `Pool` 将创建固定数量的工作进程，然后可以通过调用will create a fixed number of worker processes, and requests can then be distributed to the workers by calling `apply()` 或 `apply_async()` 来添加单个请求，通过调用 `map()` 或 `map_async()` 来添加多个请求以将请求分发给这些工作进程。 以下代码使用 `Pool` 将请求分散到 5 个工作进程并获取结果列表:

    from multiprocessing import Pool

    def factorial(N, dictionary):
        "Compute a factorial."
        ...
    p = Pool(5)
    result = p.map(factorial, range(1, 1000, 10))
    for v in result:
        print v

这会产生以下输出:

    1
    39916800
    51090942171709440000
    8222838654177922817725562880000000
    33452526613163807108170062053440751665152000000000
    ...

另一个高层级的接口，`Manager` 类，将创建一个单独的可以拥有 Python 数据结构的主副本的服务器进程。 之后其他的进程可以使用代理对象来访问和修改这些数据结构。 以下示例通过调用 `dict()` 方法创建了一个共享字典；随后工作进程可将值插入到字典中。 （不会自动为你执行锁定，这在本示例中无关紧要。 `Manager` 的方法还包括 `Lock()`, `RLock()` 和 `Semaphore()` 用于创建共享锁。）

    import time
    from multiprocessing import Pool, Manager

    def factorial(N, dictionary):
        "计算阶乘"
        # 计算结果
        fact = 1L
        for i in range(1, N+1):
            fact = fact * i

        # 将结果存储在字典中
        dictionary[N] = fact

    if __name__ == '__main__':
        p = Pool(5)
        mgr = Manager()
        d = mgr.dict()         # 创建共享字典

        # 使用池运行任务
        for N in range(1, 1000, 10):
            p.apply_async(factorial, (N, d))

        # 标记池为关闭 -- 不能再添加任务。
        p.close()

        # 等待任务退出
        p.join()

        # 输出结果
        for k, v in sorted(d.items()):
            print k, v

这将产生如下输出:

    1 1
    11 39916800
    21 51090942171709440000
    31 8222838654177922817725562880000000
    41 33452526613163807108170062053440751665152000000000
    51 15511187532873822802242430164693032110632597200169861120000...

参见

`multiprocessing` 模块的文档。

PEP 371 - 添加多任务处理包

  PEP 由 Jesse Noller 和 Richard Oudkerk 撰写，由 Richard Oudkerk 和 Jesse Noller 实现。

## PEP 3101: 高级字符串格式

在 Python 3.0 中，`%` 运算符被更强大的字符串格式化方法 `format()` 所补充。对 `str.format()` 方法的支持已经回溯到 Python 2.6。

在2.6版本中，8位字符串和Unicode字符串都有一个 `.format()` 方法，该方法将字符串视为模板，并接受要格式化的参数。格式化模板使用大括号（`{`, `}`）作为特殊字符：

    >>> # 将位置参数0替换到字符串中。
    >>> "User ID: {0}".format("root")
    'User ID: root'
    >>> # 使用命名关键字参数
    >>> "User ID: {uid}   Last seen: {last_login}".format(
    ...    uid="root",
    ...    last_login = "5 Mar 2008 07:20")
    'User ID: root   Last seen: 5 Mar 2008 07:20'

大括号可以通过双写来转义：

    >>> "Empty dict: {{}}".format()
    "Empty dict: {}"

字段名可以是表示位置参数的整数，如 `{0}`、`{1}` 等，或者是关键字参数的名称。你还可以提供复合字段名来读取属性或访问字典键：

    >>> import sys
    >>> print 'Platform: {0.platform}\nPython version: {0.version}'.format(sys)
    Platform: darwin
    Python version: 2.6a1+ (trunk:61261M, Mar  5 2008, 20:29:41)
    [GCC 4.0.1 (Apple Computer, Inc. build 5367)]'

    >>> import mimetypes
    >>> 'Content-type: {0[.mp4]}'.format(mimetypes.types_map)
    'Content-type: video/mp4'

请注意，当使用类似 `[.mp4]` 的字典样式表示法时，你不需要在字符串周围加任何引号；它将使用 `.mp4` 作为键来查找值。以数字开头的字符串将被转换为整数。你不能在格式字符串内编写更复杂的表达式。

到目前为止，我们已经展示了如何指定要替换到结果字符串中的字段。精确的格式化方式也可以通过添加一个冒号后跟一个格式说明符来控制。例如：

    >>> # 字段 0：左对齐，填充至 15 个字符
    >>> # 字段 1：右对齐，填充至 6 个字符
    >>> fmt = '{0:15} ${1:>6}'
    >>> fmt.format('Registration', 35)
    'Registration    $    35'
    >>> fmt.format('Tutorial', 50)
    'Tutorial        $    50'
    >>> fmt.format('Banquet', 125)
    'Banquet         $   125'

格式说明符可以通过嵌套来引用其他字段:

    >>> fmt = '{0:{1}}'
    >>> width = 15
    >>> fmt.format('Invoice #1234', width)
    'Invoice #1234  '
    >>> width = 35
    >>> fmt.format('Invoice #1234', width)
    'Invoice #1234                      '

可以指定所需宽度内的字段对齐方式：

字符 | 效果
--- | ---
< (默认) | 左对齐
> | 右对齐
^ | 居中对齐
= | （仅适用于数字类型）在符号后加空格。

格式说明符还可以包括一个表示类型，它控制值的格式化方式。例如，浮点数可以格式化为常规数字或指数表示法：

    >>> '{0:g}'.format(3.75)
    '3.75'
    >>> '{0:e}'.format(3.75)
    '3.750000e+00'

有多种展示类型可供选择。请参考2.6版文档中的 完整列表；以下是一个示例：

`b` | 二进制。输出以2为底的数字。
`c` | 字符。在打印之前将整数转换为相应的Unicode字符。
`d` | 十进制整数。 输出以 10 为基数的数字。
`o` | 八进制格式。 输出以 8 为基数的数字。
`x` | 十六进制格式。 输出以 16 为基数的数字，使用小写字母表示 9 以上的数码。
`e` | 指数表示法。用字母 'e' 以科学计数法打印数字以表示指数。
`g` | 通用格式。这会将数字打印为定点数，除非数字过大，在这种情况下会切换到 'e' 指数表示法。
`n` | 数字。这与 'g'（对于浮点数）或 'd'（对于整数）相同，不同之处在于它使用当前区域设置来插入适当的数字分隔符字符。
`%` | 百分比。将数字乘以100并以固定 ('f') 格式显示，后跟一个百分号。

类和类型可以定义一个 `__format__()` 方法来控制它们的格式化方式。 它接受一个参数，即格式说明符:

    def __format__(self, format_spec):
        if isinstance(format_spec, unicode):
            return unicode(str(self))
        else:
            return str(self)

还有一个内置函数 `format()` 可以格式化单个值。 它会调用类型的 `__format__()` 方法并传入给定的说明符:

    >>> format(75.6564, '.2f')
    '75.66'

参见

格式字符串语法

  格式字段的参考文档。

PEP 3101 - 高级字符串格式

  PEP 由 Eric V. Smith 撰写并实现。

## PEP 3105: `print` 改为函数

在 Python 3.0 中 `print` 语句变成了 `print()` 函数。 将 `print()` 变成函数使得可以通过 `def print(...)` 或从其他地方导入一个新函数来替换该函数。

Python 2.6 提供了 `__future__` 导入语句来移除 `print` 语法，让你可以改用函数形式。 例如:

    >>> from __future__ import print_function
    >>> print('# of entries', len(dictionary), file=sys.stderr)

新函数的签名为:

    def print(*args, sep=' ', end='\n', file=None)

形参包括:

- args: 相应值将会被打印的位置参数。

- sep: 分隔符，它将在参数之间被打印。

- end: 结束文本，它将在所有参数输出完毕之后被打印。

- file: 将被作为输出发送目标的文件对象。

参见

PEP 3105 - print 改为函数

  PEP 由 Georg Brandl 撰写。

## PEP 3110: 异常处理的变更

Python 程序员偶尔会犯的一个错误是编写这样的代码:

    try:
        ...
    except TypeError, ValueError:  # 错误！
        ...

作者可能试图捕获 `TypeError` 和 `ValueError` 异常，但这段代码实际上做了不同的事情：它会捕获 `TypeError` 并将生成的异常对象绑定到局部名称 `"ValueError"`。 `ValueError` 异常根本不会被捕获。正确的代码应指定一个异常元组：

    try:
        ...
    except (TypeError, ValueError):
        ...

这个错误发生是因为这里逗号的使用是模糊的：它是表示解析树中的两个不同节点，还是表示一个元组节点？

Python 3.0 通过将逗号替换为单词 "as" 来使这一点明确。要捕获异常并将异常对象存储在变量 `exc` 中，你必须写成：

    try:
        ...
    except TypeError as exc:
        ...

Python 3.0 将仅支持使用 "as"，因此将第一个示例解释为捕获两个不同的异常。Python 2.6 同时支持逗号和 "as"，因此现有代码将继续工作。因此，我们建议在编写仅在 2.6 上执行的新的 Python 代码时使用 "as"。

参见

PEP 3110 - 在 Python 3000 中捕获异常

  PEP 由 Collin Winter 撰写并实现。

## PEP 3112: 字节字面值

Python 3.0 采用 Unicode 作为语言的基本字符串类型，并以不同的方式表示 8 位字面量，要么作为 `b'string'`，要么使用 `bytes` 构造器。为了未来的兼容性，Python 2.6 添加了 `bytes` 作为 `str` 类型的同义词，并且也支持 `b''` 表示法。

2.6 的 `str` 与 3.0 的 `bytes` 类型在多方面存在差异；最显著的是，构造器完全不同。在 3.0 中，`bytes([65, 66, 67])` 长度为 3，包含表示 `ABC` 的字节；在 2.6 中，`bytes([65, 66, 67])` 返回表示列表的 `str()` 的 12 字节字符串。

在 2.6 中，`bytes` 的主要用途将是编写对象类型测试，例如 `isinstance(x, bytes)`。这将有助于 2to3 转换器，因为它无法判断 2.x 代码中的字符串是否意图包含字符或 8 位字节；现在你可以使用 `bytes` 或 `str` 来准确表示你的意图，并且生成的代码在 Python 3.0 中也是正确的。

还有一个 `__future__` 导入，它使所有字符串字面量变为 Unicode 字符串。这意味着可以使用 `\u` 转义序列来包含 Unicode 字符：

    from __future__ import unicode_literals

    s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
         '\u3081\u3000\u751f\u305f\u307e\u3054')

    print len(s)               # 12 个 Unicode 字符

在 C 层级上，Python 3.0 将重命名现有的 8 位字符串类型，从 Python 2.x 中的 `PyStringObject` 改为 `PyBytesObject`。 Python 2.6 使用 `#define` 来支持使用 `PyBytesObject()`, `PyBytes_Check()`, `PyBytes_FromStringAndSize()` 等名称，以及所有用于字符串的其他函数。

`bytes` 类型的实例与字符串一样属于不可变对象。 新增的 `bytearray` 类型则用于存储可变的字节序列:

    >>> bytearray([65, 66, 67])
    bytearray(b'ABC')
    >>> b = bytearray(u'\u21ef\u3244', 'utf-8')
    >>> b
    bytearray(b'\xe2\x87\xaf\xe3\x89\x84')
    >>> b[0] = '\xe3'
    >>> b
    bytearray(b'\xe3\x87\xaf\xe3\x89\x84')
    >>> unicode(str(b), 'utf-8')
    u'\u31ef \u3244'

字节数组支持大部分的字符串类型方法，如 `startswith()`/`endswith()` 、`find()`/`rfind()`，以及列表的某些方法，如 `append()`、 `pop()` 和 `reverse()`。

    >>> b = bytearray('ABC')
    >>> b.append('d')
    >>> b.append(ord('e'))
    >>> b
    bytearray(b'ABCde')

也有一个相应的 C API，包含 `PyByteArray_FromObject()`, `PyByteArray_FromStringAndSize()` 以及各种其他函数。

参见

PEP 3112 - Python 3000 中的字节字面值

  PEP 由 Jason Orendorff 撰写， 补丁2.6 由 Christian Heimes 撰写。

## PEP 3116: 新 I/O 库

Python 的内置文件对象支持多种方法，但文件型对象并不一定支持所有这些方法。 例如，模仿文件的对象通常支持 `read()` 和 `write()`，但它们可能不支持 `readline()`。 Python 3.0 在 `io` 模块中引入了一个分层的 I/O 库，它将缓冲和文本处理特性从基本读写操作中分离出来。

`io` 模块提供了三个层次的抽象基类：

- `RawIOBase` 定义了原始 I/O 操作: `read()`, `readinto()`, `write()`, `seek()`, `tell()`, `truncate()` 和 `close()`。 这个类的大多数方法通常会映射到单个系统调用。 还有 `readable()`, `writable()` 和 `seekable()` 等方法用于确定给定的对象允许哪些操作。

  Python 3.0 为文件和套接字提供了这个类的具体实现，但 Python 2.6 并没有以这种方式重新组织其文件和套接字对象。

- `BufferedIOBase` 是一个抽象基类，它在内存中缓冲数据以减少使用的系统调用次数，使 I/O 处理更为高效。 它支持 `RawIOBase` 的所有方法，并增加了一个 `raw` 属性用于存放下层的原始对象。

  有五个具体类实现了这个 ABC. `BufferedWriter` 和 `BufferedReader` 用于具有针对随机访问的 `seek()` 方法的支持只写或只读使用的对象。 `BufferedRandom` 对象支持对相同下层流的读写访问，而 `BufferedRWPair` 用于像 TTY 这样同时具有针对未连接数据流的读写操作。 `BytesIO` 类支持在内存缓冲区上进行读取、写入和定位操作。

- `TextIOBase`: 提供用于读写字符串的函数（记住，在 Python 3.0 中字符串将为 Unicode），并支持 universal newlines。 `TextIOBase` 定义了 `readline()` 方法并支持迭代对象。

  有两个具体实现。 `TextIOWrapper` 包装了一个缓冲 I/O 对象，支持所有文本 I/O 方法并增加 `buffer` 属性用于访问下层对象。 `StringIO` 简单地在内存中缓冲所有内容而不会将其写入磁盘。

  （在Python 2.6中，`io.StringIO` 是用纯Python实现的，因此相当慢。因此，你应该暂时使用现有的 `StringIO` 模块或 `cStringIO`。在某个时候，Python 3.0的 `io` 模块将被重写为C以提高速度，并且C实现可能会向下移植到2.x版本。）

在Python 2.6中，底层实现尚未重构以建立在 `io` 模块的类之上。提供该模块是为了更容易编写与3.0向前兼容的代码，并节省开发者编写自己的缓冲和文本I/O实现的努力。

参见

PEP 3116 - 新 I/O

  PEP由Daniel Stutzbach、Mike Verdone和Guido van Rossum撰写。由Guido van Rossum、Georg Brandl、Walter Doerwald、Jeremy Hylton、Martin von Löwis、Tony Lownds等人编写代码。

## PEP 3118: 修改缓冲区协议

缓冲协议是一个C级API，允许Python类型交换指向其内部表示的指针。例如，内存映射文件可以被视为字符缓冲区，这使得另一个模块如 `re` 可以将内存映射文件视为要搜索的字符字符串。

缓冲区协议的主要用户是像NumPy这样的数值处理包，它们暴露数组的内部表示，以便调用者可以直接写入数组数据，而不是通过较慢的API。这个PEP根据NumPy开发的经验更新了缓冲区协议，增加了一些新功能，例如指示数组形状或锁定内存区域。

最重要的新C API函数是 `PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)`，它接受一个对象和一组标志，并填充 `Py_buffer` 结构，包含对象内存表示的信息。对象可以使用此操作锁定内存，而外部调用者可能正在修改内容，因此有一个相应的 `PyBuffer_Release(Py_buffer *view)` 来指示外部调用者已完成。

`PyObject_GetBuffer()` 的 flags 参数指明了对所返回内存的约束。 示例如下:

- `PyBUF_WRITABLE` 指明内存必须是可写的。

- `PyBUF_LOCK` 请求一个内存上的只读或独占锁。

- `PyBUF_C_CONTIGUOUS` 和 `PyBUF_F_CONTIGUOUS` 需要 C 连续（最后一个维度变动最快）或 Fortran 连续（第一个维度变动最快）的数组布局。

两个用于 `PyArg_ParseTuple()` 的新参数代码 `s*` 和 `z*`，将为形参返回锁定的缓冲区对象。

参见

PEP 3118 - 修改缓冲区协议

  PEP 由 Travis Oliphant 和 Carl Banks 撰写，由 Travis Oliphant 实现。

## PEP 3119: 抽象基类

一些面向对象的语言如 Java 支持使用接口，即声明一个类具有一组给定的方法或支持给定的访问协议。 抽象基类 (ABC) 是 Python 中的等价特性。 ABC 支持由一个包含名为 `ABCMeta` 的元类的 `abc` 模块，由 `isinstance()` 和 `issubclass()` 内置函数提供的对该元类的特殊处理，以及一系列 Python 开发者认为会被广泛使用的基本 ABC 组成。 未来的 Python 版本可能会添加更多的 ABC。

让我们假设你有一个特定的类并想要知道它是否支持字典式访问。 然而，“字典式”一词的语意是模糊的。 它可能意味着能够通过 `obj[1]` 来访问条目。 它可能表示能够通过 `obj[2] = value` 来设置条目？ 或者这种对象具有 `keys()`, `values()` 和 `items()` 方法？ 那么是否要有迭代形式如 `iterkeys()` 呢？ `copy()` 和 `update()` 呢？ 通过 `iter()` 来迭代对象呢？

Python 2.6 `collections` 模块包括了代表这些区别的多个不同的 ABC。 `Iterable` 表明一个类定义了 `__iter__()`，而 `Container` 意味着该类定义了 `__contains__()` 方法因而支持 `x in y` 表达式。 基本的字典接口如获取条目、设置条目，以及 `keys()`, `values()` 和 `items()` 等则是由 `MutableMapping` ABC 来定义的。

你可以从特定的抽象基类派生自己的类，以表明它们支持该抽象基类的接口：

    import collections

    class Storage(collections.MutableMapping):
        ...

作为替代，你编写的类可以不从期望的 ABC 派生而是通过调用 ABC 的 `register()` 方法来注册该类:

    import collections

    class Storage:
        ...

    collections.MutableMapping.register(Storage)

对于你编写的类，从 ABC 派生可能会更清晰一些。 `register()` 方法适用于当你编写能够描述现有类型或类的新 ABC，或是当你想要声明某个实现特定 ABC 的第三方类的场合。 举例来说，如果你定义了一个 `PrintableType` ABC，这样做就是可以的:

    # 注册 Python 的类型
    PrintableType.register(int)
    PrintableType.register(float)
    PrintableType.register(str)

类应该遵守抽象基类指定的语义，但 Python 无法检查这一点；这取决于类作者理解抽象基类的要求并相应地实现代码。

要检查一个对象是否支持特定接口，你现在可以编写：

    def func(d):
        if not isinstance(d, collections.MutableMapping):
            raise ValueError("期望映射对象，而不是 %r" % d)

不要觉得你必须像上面例子那样开始编写大量检查。Python 有一种强烈的鸭子类型传统，在这种传统中，从不进行显式类型检查，代码只是简单地调用对象上的方法，相信这些方法会存在，如果不存在则会引发异常。在检查 ABC 时要明智，并且只在绝对必要时才进行检查。

你可以通过在类定义中使用 `abc.ABCMeta` 作为元类来编写自己的 ABC:

    from abc import ABCMeta, abstractmethod

    class Drawable():
        __metaclass__ = ABCMeta

        @abstractmethod
        def draw(self, x, y, scale=1.0):
            pass

        def draw_doubled(self, x, y):
            self.draw(x, y, scale=2.0)

    class Square(Drawable):
        def draw(self, x, y, scale):
            ...

在上面的 `Drawable` ABC 中，`draw_doubled()` 方法以两倍大小渲染对象并可依据 `Drawable` 描述的其他方法来实现。 因此实现此 ABC 的类不需要提供自己的 `draw_doubled()` 实现，尽管它们可以这样做。 不过，必须要有一个 `draw()` 的实现，ABC 无法提供可用的泛型实现。

你可以将 `@~abc.abstractmethod` 装饰器应用于必须实现的方法如 `draw()`；那么 Python 将针对未定义该方法的类引发异常。 请注意只有在你实际尝试创建缺少该方法的子类的实例时异常才会被引发:

    >>> class Circle(Drawable):
    ...     pass
    ...
    >>> c = Circle()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Can't instantiate abstract class Circle with abstract methods draw
    >>>

可以使用 `@abstractproperty` 装饰器声明抽象数据属性:

    from abc import abstractproperty
    ...

    @abstractproperty
    def readonly(self):
       return self._x

子类必须定义一个 `readonly` 属性。

参见

PEP 3119 - 引入抽象基类

  PEP 由 Guido van Rossum 和 Talin 编写。由 Guido van Rossum 实现。由 Benjamin Aranguren 回退到 2.6 版本，Alex Martelli 协助。

## PEP 3127: 整型文字支持和语法

Python 3.0 改变了八进制（基数为8）整数的语法，使用 "0o" 或 "0O" 作为前缀，而不是以零开头，并增加了对二进制（基数为2）整数的支持，使用 "0b" 或 "0B" 作为前缀。

Python 2.6 并没有放弃以零开头表示八进制数的支持，但增加了对 "0o" 和 "0b" 的支持:

    >>> 0o21, 2*8 + 1
    (17, 17)
    >>> 0b101111
    47

内置的 `oct()` 函数仍然返回以零开头的数字，而新的 `bin()` 函数返回数字的二进制表示:

    >>> oct(42)
    '052'
    >>> future_builtins.oct(42)
    '0o52'
    >>> bin(173)
    '0b10101101'

内置的 `int()` 和 `long()` 函数现在接受 "0o" 和 "0b" 前缀，当请求基数为8或2时，或者当 base 参数为零（表示应从字符串确定使用的基数）:

    >>> int ('0o52', 0)
    42
    >>> int('1101', 2)
    13
    >>> int('0b1101', 2)
    13
    >>> int('0b1101', 0)
    13

参见

PEP 3127 - 整型字面量支持和语法

  PEP 由 Patrick Maupin 编写；由 Eric Smith 回退到 2.6 版本。

## PEP 3129: 类装饰器

装饰器已从函数扩展到类。 现在可以合法地编写:

    @foo
    @bar
    class A:
      pass

这相当于：

    class A:
      pass

    A = foo(bar(A))

参见

PEP 3129 - 类装饰器

  PEP 由 Collin Winter 撰写。

## PEP 3141: 数字的类型层级结构

Python 3.0 增加了几种受 Scheme 数值塔启发的数值类型的抽象基类。这些类已回退到 2.6 版本，作为 `numbers` 模块。

最通用的 ABC 是 `Number`。它定义了没有任何操作，仅用于通过 `isinstance(obj, Number)` 检查对象是否为数字。

`Complex` 是 `Number` 的子类。复数可以进行加法、减法、乘法、除法和指数运算，并且可以检索实部和虚部以及获得一个数的共轭。Python 内置的复数类型是 `Complex` 的实现。

`Real` 进一步从 `Complex` 派生，并添加了仅适用于实数的操作：`floor()`，`trunc()`，四舍五入，取模 N 的余数，地板除法以及比较操作。

`Rational` 数从 `Real` 派生，具有 `numerator` 和 `denominator` 属性，并且可以转换为浮点数。Python 2.6 在 `fractions` 模块中添加了一个简单的有理数类，`Fraction`。（它被称为 `Fraction` 而不是 `Rational`，以避免与 `numbers.Rational` 名称冲突。）

`Integral` 数从 `Rational` 派生，可以使用 `<<` 和 `>>` 进行左右移位，通过按位操作（如 `&` 和 `|`）进行组合，并且可以用作数组索引和切片边界。

在 Python 3.0 中，PEP 稍微重新定义了现有的内置函数 `round()`，`math.floor()`，`math.ceil()`，并添加了一个新的函数 `math.trunc()`，该函数已被回移植到 Python 2.6。`math.trunc()` 向零舍入，返回介于函数参数和零之间的最接近的 `Integral`。

参见

PEP 3141 - 数字的类型层次结构

  PEP 由 Jeffrey Yasskin 撰写。

Scheme 的数值塔，来自 Guile 手册。

Scheme 的数字数据类型，来自 R5RS Scheme 规范。

### `fractions` 模块

为了完善数值类型的层次结构，`fractions` 模块提供了一个有理数类。有理数将它们的值存储为一个分数的分子和分母，可以精确表示诸如 `2/3` 这样的数，而浮点数只能近似表示。

`Fraction` 构造函数接受两个 `Integral` 值，这两个值将分别是结果分数的分子和分母。

    >>> 从 fractions 导入 Fraction
    >>> a = Fraction(2, 3)
    >>> b = Fraction(2, 5)
    >>> float(a), float(b)
    (0.66666666666666663, 0.40000000000000002)
    >>> a+b
    Fraction(16, 15)
    >>> a/b
    Fraction(5, 3)

为了将浮点数转换为有理数，float 类型现在有一个 `as_integer_ratio()` 方法，该方法返回一个分数的分子和分母，该分数计算结果与相同的浮点值相等:

    >>> (2.5) .as_integer_ratio()
    (5, 2)
    >>> (3.1415) .as_integer_ratio()
    (7074029114692207L, 2251799813685248L)
    >>> (1./3) .as_integer_ratio()
    (6004799503160661L, 18014398509481984L)

请注意，只能由浮点数近似表示的值，例如 1./3，不会被简化为被近似的数；分数尝试**精确**匹配浮点值。

`fractions` 模块基于 Sjoerd Mullender 的实现，该实现曾在 Python 的 `Demo/classes/` 目录中存在很长时间。这一实现由 Jeffrey Yasskin 进行了显著更新。

## 其他语言特性修改

对Python 语言核心进行的小改动：

- 包含 `__main__.py` 文件的目录和 zip 存档现在可以通过将其名称传递给解释器来直接执行。目录或 zip 存档会自动插入到 sys.path 的第一个条目中。（建议和初始补丁由 Andy Chu 提出，随后由 Phillip J. Eby 和 Nick Coghlan 修订；bpo-1739468。）

- `hasattr()` 函数在假设所有错误意味着 `__getattr__()` 方法以某种方式失败，并且 `hasattr()` 的返回值因此为 `False` 的情况下，会捕获并忽略所有错误。然而，这种逻辑不应适用于 `KeyboardInterrupt` 和 `SystemExit`；Python 2.6 在 `hasattr()` 遇到这些异常时将不再丢弃它们。（由 Benjamin Peterson 修复；bpo-2196。）

- 当使用 `**` 语法调用函数以提供关键字参数时，你不再需要使用 Python 字典；现在任何映射都将有效:

      >>> def f(**kw):
      ...    print sorted(kw)
      ...
      >>> ud=UserDict.UserDict()
      >>> ud['a'] = 1
      >>> ud['b'] = 'string'
      >>> f(**ud)
      ['a', 'b']

  （由 Alexander Belopolsky 在 bpo-1686487 中贡献。）

  在函数调用的 `*args` 参数之后提供关键字参数也是合法的。

      >>> def f(*args, **kw):
      ...     print args, kw
      ...
      >>> f(1,2,3, *(4,5,6), keyword=13)
      (1, 2, 3, 4, 5, 6) {'keyword': 13}

  在之前版本中这会导致语法错误。 （由 Amaury Forgeot d'Arc 贡献；bpo-3473。）

- 一个新的内置函数 `next(iterator, [default])` 返回指定迭代器的下一个项目。如果提供了 default 参数，当 iterator 耗尽时会返回该值；否则，将引发 `StopIteration` 异常。（已在 bpo-2719 中回溯。）

- 元组现在有了 `index()` 和 `count()` 方法，与列表类型的 `index()` 和 `count()` 方法相匹配:

      >>> t = (0,1,2,3,4,0,1,2)
      >>> t.index(3)
      3
      >>> t.count(0)
      2

  （由 Raymond Hettinger 贡献）

- 内置类型现在改进了对扩展切片语法的支持，接受各种 `(start, stop, step)` 的组合。之前，支持是部分的，某些边缘情况无法工作。（由 Thomas Wouters 实现。）

- 属性现在有三个属性，`getter`、`setter` 和 `deleter`，这些是装饰器，提供了向现有属性添加获取器、设置器或删除器函数的有用快捷方式。你可以像这样使用它们:

      class C(object):
          @property
          def x(self):
              return self._x

          @x.setter
          def x(self, value):
              self._x = value

          @x.deleter
          def x(self):
              del self._x

      class D(C):
          @C.x.getter
          def x(self):
              return self._x * 2

          @x.setter
          def x(self, value):
              self._x = value / 2

- 内置集合类型的几种方法现在接受多个可迭代对象：`intersection()`、`intersection_update()`、`union()`、`update()`、`difference()` 和 `difference_update()`。

      >>> s=set('1234567890')
      >>> s.intersection('abc123', 'cdf246')  # 所有输入的交集
      set(['2'])
      >>> s.difference('246', '789')
      set(['1', '0', '3', '5'])

  （由 Raymond Hettinger 贡献。）

- 添加了许多浮点特性。`float()` 函数现在会将字符串 `nan` 转换为 IEEE 754 非数值，将 `+inf` 和 `-inf` 转换为正无穷或负无穷。这适用于任何具有 IEEE 754 语义的平台。（由 Christian Heimes 贡献；bpo-1635。）

  `math` 模块中的其他函数，`isinf()` 和 `isnan()`，如果它们的浮点参数是无穷大或非数值，则返回真。（bpo-1640）

  添加了转换函数，用于将浮点数转换为十六进制字符串（bpo-3008）。这些函数在将浮点数转换为字符串表示形式以及从字符串表示形式转换回浮点数时，不会引入十进制和二进制之间的转换误差。浮点数有一个 `hex()` 方法，返回其字符串表示形式，而 `float.fromhex()` 方法将字符串转换回数字：

      >>> a = 3.75
      >>> a.hex()
      '0x1.e000000000000p+1'
      >>> float.fromhex('0x1.e000000000000p+1')
      3.75
      >>> b=1./3
      >>> b.hex()
      '0x1.5555555555555p-2'

- 一个数值上的细节：在支持有符号零（-0 和 +0）的系统上，从两个浮点数创建复数时，`complex()` 构造函数现在将保留零的符号。（由 Mark T. Dickinson 修复；bpo-1507。）

- 从父类继承 `__hash__()` 方法的类可以通过设置 `__hash__ = None` 来表示该类不可哈希。这将使 `hash(obj)` 抛出 `TypeError`，并且该类不会被视为实现了 `Hashable` ABC。

  当你定义了 `__cmp__()` 或 `__eq__()` 方法，且这些方法通过值而不是身份比较对象时，应该这样做。所有对象都有一个默认的哈希方法，使用 `id(obj)` 作为哈希值。没有简洁的方法来移除从父类继承的 `__hash__()` 方法，因此将 `None` 赋值作为覆盖实现。在 C 语言层面，扩展可以将 `tp_hash` 设置为 `PyObject_HashNotImplemented()`。（由 Nick Coghlan 和 Amaury Forgeot d'Arc 修复；bpo-2235。）

- `GeneratorExit` 异常现在继承自 `BaseException` 而不是 `Exception`。这意味着 `except Exception:` 的异常处理程序不会意外捕获 `GeneratorExit`。（由 Chad Austin 贡献；bpo-1537。）

- 生成器对象现在具有一个 `gi_code` 属性，该属性引用支持生成器的原始代码对象。（由 Collin Winter 贡献；bpo-1473257。）

- `compile()` 内置函数现在接受关键字参数以及位置参数。（由 Thomas Wouters 贡献；bpo-1444529。）

- `complex()` 构造函数现在接受包含括号内复数的字符串，这意味着 `complex(repr(cplx))` 现在将进行往返值。例如，`complex('(3+4j)')` 现在返回值 (3+4j)。（bpo-1491866）

- 字符串 `translate()` 方法现在接受 `None` 作为翻译表参数，这被视为身份转换。这使得仅删除字符的操作更容易进行。（由 Bengt Richter 贡献并由 Raymond Hettinger 实现；bpo-1193128。）

- 内置的 `dir()` 函数现在检查其接收对象上的 `__dir__()` 方法。该方法必须返回包含对象有效属性名称的字符串列表，并让对象控制 `dir()` 产生的值。具有 `__getattr__()` 或 `__getattribute__()` 方法的对象可以使用此方法来宣传它们将支持的伪属性。（bpo-1591665）

- 实例方法对象具有新的属性，用于构成方法的对象和函数；`im_self` 的新同义词是 `__self__`，`im_func` 也可作为 `__func__` 使用。旧名称在 Python 2.6 中仍然受支持，但在 3.0 中已移除。

- 一个不为人知的变化：当你在 `class` 语句内使用 `locals()` 函数时，生成的字典不再返回自由变量。（在这种情况下，自由变量是指在 `class` 语句中引用的但不是类属性的变量。）

### 性能优化

- `warnings` 模块已用 C 语言重写。这使得从解析器中调用警告成为可能，也可能使解释器的启动更快。（由 Neal Norwitz 和 Brett Cannon 贡献；bpo-1631171。）

- 类型对象现在有一个方法缓存，可以减少查找特定类的正确方法实现所需的工作；一旦缓存，解释器无需遍历基类来确定要调用的正确方法。如果基类或类本身被修改，缓存将被清除，因此即使在 Python 的动态特性面前，缓存也应保持正确。（最初的优化由 Armin Rigo 实现，由 Kevin Jacobs 更新以适用于 Python 2.6；bpo-1700288。）

  默认情况下，此更改仅应用于包含在 Python 核心中的类型。扩展模块可能不兼容此缓存，因此它们必须显式将 `Py_TPFLAGS_HAVE_VERSION_TAG` 添加到模块的 `tp_flags` 字段以启用方法缓存。（为了与方法缓存兼容，扩展模块的代码不得直接访问和修改其实现的任何类型的 `tp_dict` 成员。大多数模块不会这样做，但 Python 解释器无法确定这一点。参见 bpo-1878 以了解一些讨论。）

- 使用关键字参数的函数调用通过进行快速指针比较而显著加快，通常节省了完整字符串比较的时间。（由 Raymond Hettinger 贡献，基于 Antoine Pitrou 的初始实现；bpo-1819。）

- 由于在 Need For Speed sprint 中的工作，`struct` 模块中的所有函数都已用 C 语言重写。（由 Raymond Hettinger 贡献。）

- 一些标准内置类型现在在其类型对象中设置了一个位。这加快了检查对象是否为这些类型的子类的速度。（由 Neal Norwitz 贡献。）

- Unicode 字符串现在使用更快的代码来检测空白字符和换行符；这使得 `split()` 方法的速度提高了约 25%，`splitlines()` 方法的速度提高了约 35%。(由 Antoine Pitrou 贡献。) 通过使用 pymalloc 为 Unicode 字符串的数据分配内存，减少了内存使用。

- `with` 语句现在将 `__exit__()` 方法存储在堆栈上，从而产生了一小部分速度提升。(由 Jeffrey Yasskin 实现)

- 为了减少内存使用，垃圾收集器现在在收集最高代对象的垃圾时将清除内部空闲列表。这可能会更快地将内存返回给操作系统。

### 解释器改动

两个命令行选项已被保留供其他 Python 实现使用。`-J` 开关已被保留供 Jython 使用，用于 Jython 特定的选项，例如传递给底层 JVM 的开关。`-X` 已被保留用于特定 Python 实现的选项，如 CPython、Jython 或 IronPython。如果使用 Python 2.6 时使用任一选项，解释器将报告该选项当前未使用。

现在可以通过向 Python 解释器提供 `-B` 开关，或在运行解释器之前设置 `PYTHONDONTWRITEBYTECODE` 环境变量，来阻止 Python 写入 `.pyc` 或 `.pyo` 文件。此设置作为 `sys.dont_write_bytecode` 变量对 Python 程序可用，Python 代码可以更改该值以修改解释器的行为。(由 Neal Norwitz 和 Georg Brandl 贡献)

可以通过在运行解释器之前设置 `PYTHONIOENCODING` 环境变量来指定标准输入、输出和标准错误的编码。值应为形如 `<编码>` 或 `<编码>:<错误处理器>` 的字符串。编码 部分指定编码的名称，例如 `utf-8` 或 `latin-1`；可选的 错误处理器 部分指定对无法由编码处理的字符的处理方式，应为 "error"、"ignore" 或 "replace" 之一。（由 Martin von Löwis 贡献。）

## 新增和改进的模块

与每个版本一样，Python 的标准库进行了一系列增强和错误修复。以下是一些最显著变化的部分列表，按模块名称字母顺序排序。请在源树中的 `Misc/NEWS` 文件中查阅更完整的变化列表，或通过 Subversion 日志查看所有细节。

- `asyncore` 和 `asynchat` 模块再次得到积极维护，并应用了许多补丁和错误修复。（由 Josiah Carlson 维护；参见 bpo-1736190 了解其中一个补丁。）

- `bsddb` 模块也有了新的维护者 Jesús Cea Avión，该包现在可作为独立包使用。该包的网页为 www.jcea.es/programacion/pybsddb.htm。计划在 Python 3.0 中从标准库中移除该包，因为其发布频率远高于 Python。

  `bsddb.dbshelve` 模块现在使用最高可用的序列化协议，而不是限制自己使用协议 1。（由 W. Barnes 贡献。）

- `cgi` 模块现在可以从 HTTP POST 请求的查询字符串中读取变量。这使得可以使用包含查询字符串的表单操作，例如 "/cgi-bin/add.py?category=1"。（由 Alexandre Fiori 和 Nubis 贡献；bpo-1817。）

  `parse_qs()` 和 `parse_qsl()` 函数已从 `cgi` 模块移至 `urlparse` 模块。在 `cgi` 模块中仍然可用的版本将在 2.6 版本中触发 `PendingDeprecationWarning` 警告消息（bpo-600362）。

- `cmath` 模块经历了广泛的修订，由 Mark Dickinson 和 Christian Heimes 贡献。新增了五个函数：

  - `polar()` 将复数转换为极坐标形式，返回复数的模和辐角。

  - `rect()` 执行相反的操作，将模和辐角对转换回相应的复数。

  - `phase()` 返回复数的辐角（也称为角度）。

  - `isnan()` 如果其参数的实部或虚部为 NaN，则返回 True。

  - `isinf()` 如果其参数的实部或虚部为无穷大，则返回 True。

  这些修订还提高了 `cmath` 模块的数值稳定性。对于所有函数，结果的实部和虚部在可能的情况下都精确到几个最小精度单位（ulps）。详情请见 bpo-1381。`asinh()`、`atanh()` 和 `atan()` 的分支切割也已修正。

  该模块的测试已大幅扩展；近 2000 个新测试用例对代数函数进行了测试。

  在 IEEE 754 平台上，`cmath` 模块现在以符合 C99 标准附录 'G' 的方式处理 IEEE 754 特殊值和浮点异常。

- `collections` 模块中的新数据类型：`namedtuple(typename, fieldnames)` 是一个工厂函数，用于创建标准元组的子类，其字段可以通过名称和索引访问。例如：

      >>> var_type = collections.namedtuple('variable',
      ...             'id name type size')
      >>> # 名称可以用空格或逗号分隔。
      >>> # 'id, name, type, size' 也是有效的。
      >>> var_type._fields
      ('id', 'name', 'type', 'size')

      >>> var = var_type(1, 'frequency', 'int', 4)
      >>> print var[0], var.id    # 等效
      1 1
      >>> print var[2], var.type  # 等效
      int int
      >>> var._asdict()
      {'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
      >>> v2 = var._replace(name='amplitude')
      >>> v2
      variable(id=1, name='amplitude', type='int', size=4)

  标准库中多个返回元组的地方已被修改为返回 `namedtuple()` 实例。例如，`Decimal.as_tuple()` 方法现在返回一个具有 `sign`、`digits` 和 `exponent` 字段的命名元组。

  （由 Raymond Hettinger 贡献。）

- `collections` 模块的另一个变化是 `deque` 类型现在支持可选的 maxlen 参数；如果提供，deque 的大小将被限制为不超过 maxlen 项。向已满的 deque 添加更多项会导致旧项被丢弃。

      >>> from collections import deque
      >>> dq=deque(maxlen=3)
      >>> dq
      deque([], maxlen=3)
      >>> dq.append(1); dq.append(2); dq.append(3)
      >>> dq
      deque([1, 2, 3], maxlen=3)
      >>> dq.append(4)
      >>> dq
      deque([2, 3, 4], maxlen=3)

  （由 Raymond Hettinger 贡献。）

- `Cookie` 模块的 `Morsel` 对象现在支持 `httponly` 属性。在某些浏览器中，设置了此属性的 cookie 不能被 JavaScript 代码访问或操作。（由 Arvin Schnell 贡献；bpo-1638033。）

- `curses` 模块中的一个新窗口方法 `chgat()`，用于更改单行上一定数量字符的显示属性。（由 Fabian Kreutz 贡献。）

      # 从 y=0,x=21 开始的粗体文本
      # 并影响该行的其余部分。
      stdscr.chgat(0, 21, curses.A_BOLD)

  `curses.textpad` 模块中的 `Textbox` 类现在支持在插入模式和覆盖模式下编辑。通过在创建 `Textbox` 实例时为 insert_mode 参数提供真值来启用插入模式。

- `datetime` 模块的 `strftime()` 方法现在支持 `%f` 格式代码，该代码扩展为对象中的微秒数，左侧用零填充至六位。 (由 Skip Montanaro 贡献; bpo-1158.)

- `decimal` 模块已更新至 通用小数规范 的 1.66 版本。新特性包括一些基本数学函数的方法，例如 `exp()` 和 `log10()`:

      >>> Decimal(1).exp()
      Decimal("2.718281828459045235360287471")
      >>> Decimal("2.7182818").ln()
      Decimal("0.9999999895305022877376682436")
      >>> Decimal(1000).log10()
      Decimal("3")

  现在 `Decimal` 对象的 `as_tuple()` 方法将返回一个由 `sign`, `digits` 和 `exponent` 字段组成的具名元组。

  （由 Facundo Batista 和 Mark Dickinson 实现。 具名元组支持由 Raymond Hettinger 添加。）

- 现在 `difflib` 模块的 `SequenceMatcher` 类将返回代表匹配结果的具名元组，包含 `a`, `b` 和 `size` 等属性。 （由 Raymond Hettinger 贡献。）

- 在 `ftplib.FTP` 类构造函数以及 `connect()` 方法中添加了一个可选的 `timeout` 参数，用于指定以秒为单位的超时时间。 (由 Facundo Batista 添加。)此外，`FTP` 类的 `storbinary()` 和 `storlines()` 方法现在接受一个可选的 callback 参数，该参数在数据发送后会对每个数据块进行调用。 (由 Phil Schwartz 贡献; bpo-1221598.)

- 内置函数 `reduce()` 也在 `functools` 模块中提供。在 Python 3.0 中，内置函数已被移除，`reduce()` 只能从 `functools` 中获取；目前没有计划在 2.x 系列中移除该内置函数。 (由 Christian Heimes 修复; bpo-1739906.)

- 在可能的情况下，`getpass` 模块现在将使用 `/dev/tty` 来打印提示信息并读取密码，如果无法使用则回退到标准错误和标准输入。如果密码可能在终端上回显，则在显示提示之前会打印一条警告信息。 (由 Gregory P. Smith 贡献)

- `glob.glob()` 函数现在可以在使用 Unicode 路径并在目录中匹配到 Unicode 文件名时返回 Unicode 文件名。 (bpo-1001604)

- `heapq` 模块中的新函数 `merge(iter1, iter2, ...)` 接受任意数量的返回已排序数据的可迭代对象，并返回一个新的生成器，该生成器返回所有迭代器的内容，同样按顺序排序。例如:

      >>> list(heapq.merge([1, 3, 5, 9], [2, 8, 16]))
      [1, 2, 3, 5, 8, 9, 16]

  另一个新函数，`heappushpop(heap, item)`，将 item 推入 heap，然后弹出并返回最小的元素。这比先调用 `heappush()` 再调用 `heappop()` 更高效。

  `heapq` 现在实现为仅使用小于比较，而不是之前使用的小于或等于比较。这使得 `heapq` 对类型的用法与 `list.sort()` 方法一致。（由 Raymond Hettinger 贡献。）

- 可选的 `timeout` 参数，指定以秒为单位的超时时间，已添加到 `httplib.HTTPConnection` 和 `HTTPSConnection` 类构造函数中。（由 Facundo Batista 添加。）

- 大多数 `inspect` 模块的函数，如 `getmoduleinfo()` 和 `getargs()`，现在返回命名元组。除了像元组一样行为，返回值的元素也可以作为属性访问。（由 Raymond Hettinger 贡献。）

  此模块中的新增函数包括 `isgenerator()`、 `isgeneratorfunction()` 和 `isabstract()`。

- `itertools` 模块增加了几个新函数。

  `izip_longest(iter1, iter2, ...[, fillvalue])` 将基于每个元素创建元组；如果某些可迭代对象长度小于其他的，缺失的值将被设为 fillvalue。 例如:

      >>> tuple(itertools.izip_longest([1,2,3], [1,2,3,4,5]))
      ((1, 1), (2, 2), (3, 3), (None, 4), (None, 5))

  `product(iter1, iter2, ..., [repeat=N])` 将返回所提供可迭代对象的笛卡尔积，即包含从每个可迭代对象返回的元素的每种可能组合的元组的集合。:

      >>> list(itertools.product([1,2,3], [4,5,6]))
      [(1, 4), (1, 5), (1, 6),
       (2, 4), (2, 5), (2, 6),
       (3, 4), (3, 5), (3, 6)]

  可选的*repeat*关键字参数用于计算一个可迭代对象或一组可迭代对象与其自身重复*N*次后的乘积。对于单个可迭代对象参数，返回*N*-元组:

      >>> list(itertools.product([1,2], repeat=3))
      [(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
       (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]

  对于两个可迭代对象，返回*2N*-元组。:

      >>> list(itertools.product([1,2], [3,4], repeat=2))
      [(1, 3, 1, 3), (1, 3, 1, 4), (1, 3, 2, 3), (1, 3, 2, 4),
       (1, 4, 1, 3), (1, 4, 1, 4), (1, 4, 2, 3), (1, 4, 2, 4),
       (2, 3, 1, 3), (2, 3, 1, 4), (2, 3, 2, 3), (2, 3, 2, 4),
       (2, 4, 1, 3), (2, 4, 1, 4), (2, 4, 2, 3), (2, 4, 2, 4)]

  `combinations(iterable, r)` 基于 iterable 的元素返回长度为 r 的子序列。

      >>> list(itertools.combinations('123', 2))
      [('1', '2'), ('1', '3'), ('2', '3')]
      >>> list(itertools.combinations('123', 3))
      [('1', '2', '3')]
      >>> list(itertools.combinations('1234', 3))
      [('1', '2', '3'), ('1', '2', '4'),
       ('1', '3', '4'), ('2', '3', '4')]

  `permutations(iter[, r])` 返回可迭代对象元素长度为 r 的所有排列。如果未指定 r，则默认为可迭代对象产生的元素数量。:

      >>> list(itertools.permutations([1,2,3,4], 2))
      [(1, 2), (1, 3), (1, 4),
       (2, 1), (2, 3), (2, 4),
       (3, 1), (3, 2), (3, 4),
       (4, 1), (4, 2), (4, 3)]

  `itertools.chain(*iterables)` 是 `itertools` 模块中已有的一个函数，在 Python 2.6 中新增了一个构造器。`itertools.chain.from_iterable(iterable)` 接受一个应返回其他可迭代对象的单一可迭代对象。`chain()` 将依次返回第一个可迭代对象的所有元素，然后是第二个可迭代对象的所有元素，依此类推。:

      >>> list(itertools.chain.from_iterable([[1,2,3], [4,5,6]]))
      [1, 2, 3, 4, 5, 6]

  （全部由 Raymond Hettinger 贡献。）

- `logging` 模块的 `FileHandler` 类及其子类 `WatchedFileHandler`、`RotatingFileHandler` 和 `TimedRotatingFileHandler` 现在在其构造器中有一个可选的 delay 参数。如果 delay 为真，日志文件的打开将被延迟，直到第一次调用 `emit()`。 (由 Vinay Sajip 贡献)

  `TimedRotatingFileHandler` 还有一个 utc 构造器参数。如果该参数为真，将使用 UTC 时间来确定午夜时刻和生成文件名；否则将使用本地时间。

- 为 `math` 模块添加了一些新函数:

  - `isinf()` 和 `isnan()` 分别用于判断给定浮点数是否为（正或负）无穷大或 NaN（非数字）。

  - `copysign()` 复制 IEEE 754 数的符号位，返回 x 的绝对值与 y 的符号位组合的结果。例如，`math.copysign(1, -0.0)` 返回 -1.0。 (由 Christian Heimes 贡献)

  - `factorial()` 计算一个数的阶乘。 (由 Raymond Hettinger 贡献；bpo-2138)

  - `fsum()` 将可迭代对象中的数字流相加，并小心避免通过使用部分和来损失精度。 (由 Jean Brouwers、Raymond Hettinger 和 Mark Dickinson 贡献；bpo-2819)

  - `acosh()`、`asinh()` 和 `atanh()` 计算反双曲函数。

  - `log1p()` 返回 1+x (以 e 为底) 的自然对数。

  - `trunc()` 将数字四舍五入至零，返回介于函数参数和零之间的最接近的 `Integral`。作为 PEP 3141 数字类型层次结构 的回退部分添加。

- `math` 模块已改进，以在不同平台上提供更一致的行为，特别是在处理浮点异常和 IEEE 754 特殊值方面。

  在可能的情况下，该模块遵循 C99 标准关于 754 特殊值的建议。例如，`sqrt(-1.)` 现在应在几乎所有平台上引发 `ValueError`，而 `sqrt(float('NaN'))` 应在所有 IEEE 754 平台上返回 NaN。在 C99 标准附件 'F' 建议发出 '除以零' 或 '无效' 信号的地方，Python 将引发 `ValueError`。在 C99 标准附件 'F' 建议发出 '溢出' 信号的地方，Python 将引发 `OverflowError`。（参见 bpo-711019 和 bpo-1640。）

  （由 Christian Heimes 和 Mark Dickinson 贡献。）

- `mmap` 对象现在有一个 `rfind()` 方法，从字符串末尾开始向后搜索子字符串。`find()` 方法还增加了一个 end 参数，用于指定停止搜索的索引。（由 John Lenton 贡献。）

- `operator` 模块增加了一个 `methodcaller()` 函数，它接受一个名称和一组可选的参数，返回一个可调用的对象，该对象将对传递给它的任何参数调用指定的函数。例如：

      >>> # 等价于 lambda s: s.replace('old', 'new')
      >>> replacer = operator.methodcaller('replace', 'old', 'new')
      >>> replacer('old wine in old bottles')
      'new wine in new bottles'

  （由 Gregory Petrosyan 提供建议，之后由 Georg Brandl 贡献。）

  现在 `attrgetter()` 函数可接受带点号的名称并执行相应的属性查找:

      >>> inst_name = operator.attrgetter(
      ...        '__class__.__name__')
      >>> inst_name('')
      'str'
      >>> inst_name(help)
      '_Helper'

  （由 Barry Warsaw 提供建议，之后由 Georg Brandl 贡献。）

- `os` 模块现在包装了几个新的系统调用。`fchmod(fd, mode)` 和 `fchown(fd, uid, gid)` 更改已打开文件的模式和所有权，`lchmod(path, mode)` 更改符号链接的模式。（由 Georg Brandl 和 Christian Heimes 贡献。）

  `chflags()` 和 `lchflags()` 是对应系统调用（在可用的情况下）的封装，用于更改文件上的标志。标志值的常量在 `stat` 模块中定义；一些可能的值包括 `UF_IMMUTABLE` 表示文件不可更改，以及 `UF_APPEND` 表示数据只能追加到文件中。（由 M. Levinson 贡献。）

  `os.closerange(low, high)` 高效地关闭从 low 到 high 的所有文件描述符，忽略任何错误，并且不包括 high 本身。此函数现在被 `subprocess` 模块使用，以加快启动进程的速度。（由 Georg Brandl 贡献；bpo-1663329。）

- `os.environ` 对象的 `clear()` 方法现在除了清除对象的键之外，还会使用 `os.unsetenv()` 来取消设置环境变量。（由 Martin Horcicka 贡献；bpo-1181。）

- `os.walk()` 函数现在有一个 `followlinks` 参数。如果设置为 True，它将跟随指向目录的符号链接并访问目录的内容。为了向后兼容，该参数的默认值为 false。请注意，如果存在指向父目录的符号链接，该函数可能会陷入无限递归。（bpo-1273829）

- 在 `os.path` 模块中，`splitext()` 函数已更改，不再在开头的句点字符处分割。这在处理 Unix 的点文件时会产生更好的结果。例如，`os.path.splitext('.ipython')` 现在返回 `('.ipython', '')` 而不是 `('', '.ipython')`。（bpo-1115886）

  一个新的函数，`os.path.relpath(path, start='.')`，返回从 `start` 路径（如果提供）或从当前工作目录到目标 `path` 的相对路径。（由 Richard Barran 贡献；bpo-1339796。）

  在Windows上，`os.path.expandvars()` 现在可以展开形如 "%var%" 的环境变量，并且 "~user" 将被展开为用户的主目录路径。（由 Josiah Carlson 贡献；bpo-957650。）

- `pdb` 模块提供的 Python 调试器新增了一个命令："run" 可以重新启动正在调试的 Python 程序，并且可以可选地接受新的命令行参数。（由 Rocky Bernstein 贡献；bpo-1393667。）

- 用于开始调试回溯的 `pdb.post_mortem()` 函数，现在如果没有提供回溯，将使用 `sys.exc_info()` 返回的回溯。（由 Facundo Batista 贡献；bpo-1106316。）

- `pickletools` 模块现在有一个 `optimize()` 函数，它接受一个包含 pickle 的字符串，并移除一些未使用的操作码，返回一个包含相同数据结构的更短的 pickle。（由 Raymond Hettinger 贡献。）

- 在 `pkgutil` 模块中添加了一个 `get_data()` 函数，它返回随安装的 Python 包一起包含的资源文件的内容。例如：

      >>> import pkgutil
      >>> print pkgutil.get_data('test', 'exception_hierarchy.txt')
      BaseException
       +-- SystemExit
       +-- KeyboardInterrupt
       +-- GeneratorExit
       +-- Exception
            +-- StopIteration
            +-- StandardError
       ...

  （由 Paul Moore 在 bpo-2439 中贡献。）

- `pyexpat` 模块的 `Parser` 对象现在允许设置它们的 `buffer_size` 属性，以改变用于保存字符数据的缓冲区大小。（由 Achim Gaedke 贡献；bpo-1137。）

- `Queue` 模块现在提供了不同顺序检索条目的队列变体。`PriorityQueue` 类将排队项存储在堆中并按优先级顺序检索它们，而 `LifoQueue` 首先检索最近添加的条目，这意味着它表现得像一个栈。（由 Raymond Hettinger 贡献。）

- `random` 模块的 `Random` 对象现在可以在32位系统上被序列化，并在64位系统上反序列化，反之亦然。不幸的是，这一变化也意味着 Python 2.6 的 `Random` 对象无法在早期版本的 Python 上正确反序列化。（由 Shawn Ligocki 贡献；bpo-1727780。）

  新的 `triangular(low, high, mode)` 函数返回遵循三角分布的随机数。返回值介于 low 和 high 之间，不包括 high 本身，且 mode 为分布中最频繁出现的值。（由 Wladmir van der Laan 和 Raymond Hettinger 贡献；bpo-1681432。）

- `re` 模块执行的长正则表达式搜索将检查是否有信号传递，因此耗时搜索现在可以被中断。（由 Josh Hoyt 和 Ralf Schmitt 贡献；bpo-846388。）

  正则表达式模块通过为一个小型正则表达式专用虚拟机编译字节码来实现。未受信任的代码可能直接创建恶意的字节码字符串并导致崩溃，因此 Python 2.6 包含了一个用于验证正则表达式字节码的验证器。（由 Guido van Rossum 基于为 Google App Engine 的工作贡献；bpo-3487。）

- `rlcompleter` 模块的 `Completer.complete()` 方法现在将忽略在评估名称时触发的异常。（由 Lorenz Quack 修复；bpo-2250。）

- `sched` 模块的 `scheduler` 实例现在有一个只读的 `queue` 属性，返回调度器队列的内容，表示为一个命名元组列表，字段为 `(time, priority, action, argument)`。（由 Raymond Hettinger 贡献；bpo-1861。）

- 模块 `select` 现在为 Linux 的 `epoll()` 和 BSD 的 `kqueue()` 系统调用提供了包装函数。为现有的 `poll` 对象添加了 `modify()` 方法；`pollobj.modify(fd, eventmask)` 接收一个文件描述符或文件对象以及一个事件掩码，修改该文件的记录事件掩码。（由 Christian Heimes 贡献；bpo-1657。）

- 函数 `shutil.copytree()` 现在有一个可选的 ignore 参数，该参数接收一个可调用对象。这个可调用对象将接收每个目录路径和目录内容的列表，并返回一个将被忽略、不进行复制的名称列表。

  模块 `shutil` 还提供了一个 `ignore_patterns()` 函数，用于与这个新参数一起使用。`ignore_patterns()` 接收任意数量的 glob-style 模式，并返回一个可调用对象，该对象将忽略匹配这些模式中的任何一个的文件和目录。以下示例复制一个目录树，但跳过 `.svn` 目录和以 '~' 结尾的 Emacs 备份文件：

      shutil.copytree('Doc/library', '/tmp/library',
                      ignore=shutil.ignore_patterns('*~', '.svn'))

  （由 Tarek Ziadé 在 bpo-2663 中贡献。）

- 将信号处理与 Tkinter 或 GTk+ 使用的 GUI 事件循环集成长期以来一直是一个问题；大多数软件最终采用轮询方式，每隔一小段时间唤醒一次以检查是否有任何 GUI 事件发生。模块 `signal` 现在可以使这更高效。调用 `signal.set_wakeup_fd(fd)` 设置一个文件描述符；当接收到信号时，向该文件描述符写入一个字节。还有一个 C 级函数 `PySignal_SetWakeupFd()`，用于设置描述符。

  事件循环将使用此方法通过打开管道来创建两个描述符，一个用于读取，一个用于写入。可写描述符将传递给 `set_wakeup_fd()`，可读描述符将通过 `select()` 或 `poll()` 添加到事件循环监视的描述符列表中。接收到信号时，将写入一个字节，唤醒主事件循环，避免需要轮询。

  （由 Adam Olsen 在 bpo-1583 中贡献。）

  `siginterrupt()` 函数现在可以从 Python 代码中使用，允许更改信号是否可以中断系统调用。（由 Ralf Schmitt 贡献。）

  还添加了 `setitimer()` 和 `getitimer()` 函数（在可用的情况下）。`setitimer()` 允许设置间隔定时器，该定时器将在指定时间后向进程发送信号，时间测量可以是墙钟时间、消耗的进程时间或进程+系统时间之和。（由 Guilherme Polo 贡献；bpo-2240。）

- `smtplib` 模块现在支持通过 SSL 的 SMTP，这得益于 `SMTP_SSL` 类的添加。这个类支持与现有 `SMTP` 类相同的接口。（由 Monty Taylor 贡献。）这两个类构造函数还有一个可选的 `timeout` 参数，用于指定初始连接尝试的超时时间，以秒为单位。（由 Facundo Batista 贡献。）

  模块中还添加了 LMTP 协议（RFC 2033）的实现。当在不需要管理邮件队列的代理之间传输电子邮件时，使用 LMTP 代替 SMTP。（LMTP 由 Leif Hedstrom 实现；bpo-957003。）

  `SMTP.starttls()` 现在符合 RFC 3207 标准，并忘记从服务器获得的任何非 TLS 协商本身获得的知识。（补丁由 Bill Fenner 贡献；bpo-829951。）

- `socket` 模块现在支持 TIPC (https://tipc.sourceforge.net/)，这是一种为集群环境设计的高性能非IP协议。TIPC 地址为 4- 或 5- 元组。（由 Alberto Bertogli 贡献；bpo-1646。）

  新函数 `create_connection()` 接收一个地址并使用可选的超时值进行连接，返回已连接的套接字对象。此函数还会查找地址的类型，并使用 IPv4 或 IPv6 适当地进行连接。将代码改为使用 `create_connection()` 而不是 `socket(socket.AF_INET, ...)` 可能是使代码支持 IPv6 所需的全部工作。

- `SocketServer` 模块中的基类现在支持在服务器 `timeout` 属性指定的不活动时间后调用 `handle_timeout()` 方法。(由 Michael Pomraning 贡献。) `serve_forever()` 方法现在接受一个可选的轮询间隔（以秒为单位），控制服务器检查关闭请求的频率。（由 Pedro Werneck 和 Jeffrey Yasskin 贡献；bpo-742598, bpo-1193577。）

- 由 Gerhard Häring 维护的 `sqlite3` 模块已从 Python 2.5 中的版本 2.3.2 更新到版本 2.4.1。

- `struct` 模块现在支持 C99 的 _Bool 类型，使用格式字符 `'?'`。（由 David Remahl 贡献。）

- `subprocess` 模块提供的 `Popen` 对象现在具有 `terminate()`、`kill()` 和 `send_signal()` 方法。在 Windows 上，`send_signal()` 仅支持 `SIGTERM` 信号，所有这些方法都是 Win32 API 函数 `TerminateProcess()` 的别名。（由 Christian Heimes 贡献。)

- 在 `sys` 模块中新增了一个变量 `float_info`，它是一个包含从 `float.h` 文件中获取的关于平台浮点支持信息的对象。该对象的属性包括 `mant_dig` (尾数的位数) 、`epsilon` (1.0 与下一个可表示的最大值之间的最小差值) 以及其他几个属性。（由 Christian Heimes 贡献；bpo-1534。）

  另一个新变量 `dont_write_bytecode` 控制着 Python 在导入模块时是否写入任何 `.pyc` 或 `.pyo` 文件。如果该变量为真，则不写入编译文件。该变量在启动时通过向 Python 解释器提供 `-B` 开关或通过在运行解释器之前设置 `PYTHONDONTWRITEBYTECODE` 环境变量来初始设置。Python 代码随后可以更改此变量的值，以控制是否写入字节码文件。（由 Neal Norwitz 和 Georg Brandl 贡献。）

  通过读取名为 `sys.flags` 的命名元组的属性，可以获取提供给 Python 解释器的命令行参数信息。例如，如果 Python 以详细模式执行，则 `verbose` 属性为真，`debug` 在调试模式下为真，等等。这些属性都是只读的。（由 Christian Heimes 贡献。）

  新增了一个函数 `getsizeof()`，它接受一个 Python 对象并返回该对象使用的内存量，以字节为单位。内置对象返回正确结果；第三方扩展可能不会，但可以定义一个 `__sizeof__()` 方法来返回对象的大小。（由 Robert Schuppenies 贡献；bpo-2898。）

  现在可以通过调用 `sys.getprofile()` 和 `sys.gettrace()` 来确定当前的剖析器和跟踪器函数。（由 Georg Brandl 贡献；bpo-1648。）

- 模块 `tarfile` 现在除了已支持的 POSIX.1-1988 (ustar) 和 GNU tar 格式外，还支持 POSIX.1-2001 (pax) tar文件。默认格式为 GNU tar；可以通过指定 `format` 参数来使用不同的格式打开文件:

      tar = tarfile.open("output.tar", "w",
                         format=tarfile.PAX_FORMAT)

  新的 `encoding` 和 `errors` 参数用于指定字符转换的编码和错误处理方案。`'strict'`、`'ignore'` 和 `'replace'` 是 Python 处理错误的三个标准方式；`'utf-8'` 是一个特殊值，它会将错误的字符替换为它们的 UTF-8 表示形式。（字符转换是因为 PAX 格式支持 Unicode 文件名，默认使用 UTF-8 编码。）

  方法 `TarFile.add()` 现在接受一个 `exclude` 参数，该参数是一个函数，用于排除某些文件名不存入归档。该函数必须接受一个文件名，并在文件应被排除时返回 true，在文件应被归档时返回 false。该函数应用于最初传递给 `add()` 的名称以及递归添加的目录中的文件名。

  （所有改变均由 Lars Gustäbel 贡献）。

- 在类 `telnetlib.Telnet` 的构造函数中添加了一个可选的 `timeout` 参数，用于指定以秒为单位的超时时间。（由 Facundo Batista 添加。）

- 类 `tempfile.NamedTemporaryFile` 通常在文件关闭时删除其创建的临时文件。现在可以通过向构造函数传递 `delete=False` 来改变此行为。（由 Damien Miller 贡献；bpo-1537850。）

  新增类 `SpooledTemporaryFile`，其行为类似于临时文件，但会在内存中存储数据，直到超过最大大小。达到该限制后，内容将被写入磁盘上的临时文件。（由 Dustin J. Mitchell 贡献。）

  `NamedTemporaryFile` 和 `SpooledTemporaryFile` 类都可作为上下文管理器使用，因此你可以编写 `with tempfile.NamedTemporaryFile() as tmp: ...`。 (由 Alexander Belopolsky 贡献; bpo-2021.)

- `test.test_support` 模块增加了一些用于编写测试的上下文管理器。`EnvironmentVarGuard()` 是一个上下文管理器，它可以临时更改环境变量并自动将其恢复为旧值。

  另一个上下文管理器 `TransientResource` 可以围绕对可能可用或不可用的资源的调用；它将捕获并忽略指定的异常列表。例如，网络测试在连接到外部网站时可能会忽略某些失败情况:

      with test_support.TransientResource(IOError,
                                      errno=errno.ETIMEDOUT):
          f = urllib.urlopen('https://sf.net')
          ...

  最后，`check_warnings()` 重置 `warning` 模块的警告过滤器，并返回一个将记录所有触发的警告消息的对象 (bpo-3781):

      with test_support.check_warnings() as wrec:
          warnings.simplefilter("always")
          # ... 触发警告的代码 ...
          assert str(wrec.message) == "function is outdated"
          assert len(wrec.warnings) == 1, "Multiple warnings raised"

  （由 Brett Cannon 贡献。）

- `textwrap` 模块现在可以通过指定 `drop_whitespace=False` 作为参数来保留新创建行首尾的现有空白:

      >>> S = """This  sentence  has a bunch   of
      ...   extra   whitespace."""
      >>> print textwrap.fill(S, width=15)
      This  sentence
      has a bunch
      of    extra
      whitespace.
      >>> print textwrap.fill(S, drop_whitespace=False, width=15)
      This  sentence
        has a bunch
         of    extra
         whitespace.
      >>>

  （由 Dwayne Bailey 在 bpo-1581073 中贡献。）

- 模块 `threading` 的 API 正在被修改，以使用属性如 `daemon` 而不是 `setDaemon()` 和 `isDaemon()` 方法，并且一些方法已被重命名，使用下划线而不是驼峰命名法；例如，`activeCount()` 方法被重命名为 `active_count()`。模块的 2.6 和 3.0 版本都支持相同的属性和重命名的方法，但不删除旧方法。Python 3.x 中旧 API 的弃用日期尚未确定；旧 API 不会在任何 2.x 版本中被移除。（由多人执行，最著名的是 Benjamin Peterson。）

  模块 `threading` 的 `Thread` 对象获得了一个 `ident` 属性，该属性返回线程的标识符，一个非零整数。（由 Gregory P. Smith 贡献；bpo-2871。）

- 模块 `timeit` 现在接受可调用对象以及字符串作为被计时的语句和设置代码。添加了两个便捷函数用于创建 `Timer` 实例：`repeat(stmt, setup, time, repeat, number)` 和 `timeit(stmt, setup, time, number)` 创建一个实例并调用相应的方法。（由 Erik Demaine 贡献；bpo-1533909。）

- 模块 `Tkinter` 现在接受列表和元组作为选项，在将结果值传递给 Tcl/Tk 之前用空格分隔元素。（由 Guilherme Polo 贡献；bpo-2906。）

- 模块 `turtle` 用于海龟图形，由 Gregor Lingl 大大增强。模块中的新功能包括：

  - 改进了海龟移动和旋转的动画。

  - 使用新的 `delay()`、`tracer()` 和 `speed()` 方法控制海龟移动。

  - 能够为海龟设置新形状，并定义新的坐标系。

  - 海龟现在有一个 `undo()` 方法，可以回滚操作。

  - 简单支持对鼠标和键盘活动等输入事件做出反应，使得编写简单游戏成为可能。

  - `turtle.cfg` 文件可被用来定制海龟绘图屏幕的初始外观。

  - 模块的文档字符串可以被替换为已翻译成另一种语言的新文档字符串。

  (bpo-1513695)

- 在 `urllib.urlopen` 函数和 `urllib.ftpwrapper` 类构造器以及 `urllib2.urlopen` 函数中添加了一个可选的 `timeout` 参数。该参数指定以秒为单位的超时时间。例如:

      >>> u = urllib2.urlopen("http://slow.example.com",
                              timeout=3)
      Traceback (most recent call last):
        ...
      urllib2.URLError: <urlopen error timed out>
      >>>

  （由 Facundo Batista 添加。）

- `unicodedata` 模块提供的Unicode数据库已更新至版本5.1.0。（由Martin von Löwis更新；bpo-3811。）

- `warnings` 模块的 `formatwarning()` 和 `showwarning()` 增加了一个可选的 line 参数，用于提供源代码行。（作为 bpo-1631171 的一部分添加，该问题重新实现了 `warnings` 模块的C代码部分。）

  新增函数 `catch_warnings()` 是一个用于测试目的的上下文管理器，允许你临时修改警告过滤器，然后恢复其原始值（bpo-3781）。

- XML-RPC的 `SimpleXMLRPCServer` 和 `DocXMLRPCServer` 类现在可以通过将 `False` 作为 bind_and_activate 构造器参数传递来防止立即打开并绑定到其套接字。这可用于在调用 `server_bind()` 和 `server_activate()` 方法打开套接字并开始监听连接之前修改实例的 `allow_reuse_address` 属性。（由Peter Parente贡献；bpo-1599845。）

  `SimpleXMLRPCServer` 还有一个 `_send_traceback_header` 属性；如果为真，异常和格式化的回溯将作为 HTTP 头部 "X-Exception" 和 "X-Traceback" 返回。此功能仅用于调试目的，不应在生产服务器上使用，因为回溯可能会泄露密码或其他敏感信息。（由 Alan McIntyre 作为其 Google 2007 年夏季代码项目的一部分贡献。）

- `xmlrpclib` 模块不再自动将 `datetime.date` 和 `datetime.time` 转换为 `xmlrpclib.DateTime` 类型；转换语义并不一定适用于所有应用程序。使用 `xmlrpclib` 的代码应转换 `date` 和 `time` 实例。（bpo-1330538）代码还可以处理 1900 年之前的日期（由 Ralf Schmitt 贡献；bpo-2014）以及使用 `<i8>` 在 XML-RPC 响应中表示的 64 位整数（由 Riku Lindblad 贡献；bpo-2985）。

- `zipfile` 模块的 `ZipFile` 类现在有 `extract()` 和 `extractall()` 方法，可以将单个文件或存档中的所有文件解压到当前目录，或指定目录:

      z = zipfile.ZipFile('python-251.zip')

      # 解压单个文件，将其写入
      # 相对于 /tmp 目录。
      z.extract('Python/sysmodule.c', '/tmp')

      # 解压存档中的所有文件。
      z.extractall()

  （由 Alan McIntyre 在 bpo-467924 中贡献。）

  `open()`、`read()` 和 `extract()` 方法现在可以接受文件名或 `ZipInfo` 对象。这在存档意外包含重复文件名时很有用。（由 Graham Horler 贡献；bpo-1775025。）

  最后，`zipfile` 现在支持使用 Unicode 文件名存档文件。（由 Alexey Borzenkov 贡献；bpo-1734346。）

### `ast` 模块

`ast` 模块提供了 Python 代码的抽象语法树（Abstract Syntax Tree）表示，Armin Ronacher 贡献了一组辅助函数，用于执行各种常见任务。这些函数对于 HTML 模板包、代码分析器以及处理 Python 代码的类似工具将非常有用。

`parse()` 函数接受一个表达式并返回一个 AST。`dump()` 函数输出树的表示，适用于调试:

    import ast

    t = ast.parse("""
    d = {}
    for i in 'abcdefghijklm':
        d[i + i] = ord(i) - ord('a') + 1
    print d
    """)
    print ast.dump(t)

输出是一棵深度嵌套的树:

    Module(body=[
      Assign(targets=[
        Name(id='d', ctx=Store())
       ], value=Dict(keys=[], values=[]))
      For(target=Name(id='i', ctx=Store()),
          iter=Str(s='abcdefghijklm'), body=[
        Assign(targets=[
          Subscript(value=
            Name(id='d', ctx=Load()),
              slice=
              Index(value=
                BinOp(left=Name(id='i', ctx=Load()), op=Add(),
                 right=Name(id='i', ctx=Load()))), ctx=Store())
         ], value=
         BinOp(left=
          BinOp(left=
           Call(func=
            Name(id='ord', ctx=Load()), args=[
              Name(id='i', ctx=Load())
             ], keywords=[], starargs=None, kwargs=None),
           op=Sub(), right=Call(func=
            Name(id='ord', ctx=Load()), args=[
              Str(s='a')
             ], keywords=[], starargs=None, kwargs=None)),
           op=Add(), right=Num(n=1)))
        ], orelse=[])
       Print(dest=None, values=[
         Name(id='d', ctx=Load())
       ], nl=True)
     ])

`literal_eval()` 方法接受一个字符串或表示字面量表达式的 AST，解析并评估它，并返回结果值。字面量表达式是只包含字符串、数字、字典等，但不包含语句或函数调用的 Python 表达式。如果你需要评估一个表达式，但不能接受使用 `eval()` 调用的安全风险，`literal_eval()` 将安全地处理它:

    >>> literal = '("a", "b", {2:4, 3:8, 1:2})'
    >>> print ast.literal_eval(literal)
    ('a', 'b', {1: 2, 2: 4, 3: 8})
    >>> print ast.literal_eval('"a" + "b"')
    Traceback (most recent call last):
      ...
    ValueError: malformed string

该模块还包括 `NodeVisitor` 和 `NodeTransformer` 类，用于遍历和修改 AST，以及用于常见转换（如更改行号）的函数。

### `future_builtins` 模块

Python 3.0 对内置函数库进行了许多更改，大多数更改无法在 Python 2.x 系统中引入因为它们会破坏兼容性。 `future_builtins` 模块提供了这些内置函数的不同版本，可以在编写 3.0 兼容的代码时导入。

目前此模块中的函数包括:

- `ascii(obj)`: 等同于 `repr()`。在 Python 3.0 中，`repr()` 将返回一个 Unicode 字符串，而 `ascii()` 将返回一个纯 ASCII 字节串。

- `filter(predicate, iterable)`, `map(func, iterable1, ...)`: 3.0 版本返回迭代器，与返回列表的 2.x 内置函数不同。

- `hex(value)`, `oct(value)`: 这些版本将调用 `__index__()` 方法而不是 `__hex__()` 或 `__oct__()` 方法，并将结果转换为十六进制或八进制。`oct()` 将使用新的 `0o` 表示法来表示其结果。

### `json` 模块: JavaScript Object Notation

新的 `json` 模块支持将 Python 类型编码和解码为 JSON（JavaScript 对象表示法）。JSON 是一种轻量级的数据交换格式，常用于 Web 应用程序。有关 JSON 的更多信息，请参见 http://www.json.org。

`json` 模块支持对大多数内置 Python 类型进行解码和编码。以下示例展示了如何编码和解码字典:

    >>> import json
    >>> data = {"spam": "foo", "parrot": 42}
    >>> in_json = json.dumps(data) # 编码数据
    >>> in_json
    '{"parrot": 42, "spam": "foo"}'
    >>> json.loads(in_json) # 解码到一个 Python 对象
    {"spam": "foo", "parrot": 42}

你还可以编写自己的解码器和编码器以支持更多类型。还支持对 JSON 字符串进行美化打印。

`json` (最初称为 simplejson) 由 Bob Ippolito 编写。

### `plistlib` 模块：属性列表解析器

`.plist` 格式通常在 Mac OS X 上用于存储基本数据类型（数字、字符串、列表和字典），通过将它们序列化成基于 XML 的格式。它类似于 XML-RPC 数据类型的序列化。

尽管该格式主要在 Mac OS X 上使用，但它本身并没有特定于 Mac 的内容，Python 实现在任何支持 Python 的平台上都能工作，因此 `plistlib` 模块已被提升到标准库中。

此模块的用法很简单:

    import sys
    import plistlib
    import datetime

    # 创建数据结构
    data_struct = dict(lastAccessed=datetime.datetime.now(),
                       version=1,
                       categories=('Personal','Shared','Private'))

    # 创建包含 XML 的字符串。
    plist_str = plistlib.writePlistToString(data_struct)
    new_struct = plistlib.readPlistFromString(plist_str)
    print data_struct
    print new_struct

    # 将数据结构写入文件并重新读取。
    plistlib.writePlist(data_struct, '/tmp/customizations.plist')
    new_struct = plistlib.readPlist('/tmp/customizations.plist')

    # read/writePlist 接受文件类对象以及路径。
    plistlib.writePlist(data_struct, sys.stdout)

### ctypes 增强

Thomas Heller 继续维护和增强 `ctypes` 模块。

`ctypes` 现在支持 `c_bool` 数据类型，它表示 C99 的 `bool` 类型。（由 David Remahl 贡献；bpo-1649190。）

`ctypes` 模块的字符串、缓冲区和数组类型已改进对扩展切片语法的支持，可以提供各种 `(start, stop, step)` 组合。（由 Thomas Wouters 实现。）

所有 `ctypes` 数据类型现在支持 `from_buffer()` 和 `from_buffer_copy()` 方法，这些方法基于提供的缓冲区对象创建 ctypes 实例。`from_buffer_copy()` 方法复制对象的内容，而 `from_buffer()` 方法将共享同一内存区域。

新的调用约定指示 `ctypes` 在每次包装调用的开始清除 `errno` 或 Win32 LastError 变量。（由 Thomas Heller 实现；bpo-1798。）

现在可以在函数调用后检索 Unix `errno` 变量。在创建包装函数时，可以将 `use_errno=True` 作为关键字参数提供给 `DLL()` 函数，然后调用模块级方法 `set_errno()` 和 `get_errno()` 来设置和检索错误值。

Win32 LastError 变量同样由 `DLL()`、`OleDLL()` 和 `WinDLL()` 函数支持。提供 `use_last_error=True` 作为关键字参数，然后调用模块级方法 `set_last_error()` 和 `get_last_error()`。

`byref()` 函数用于检索指向 ctypes 实例的指针，现在有一个可选的 offset 参数，该参数是一个字节计数，将添加到返回的指针中。

### 改进的 SSL 支持

Bill Janssen 对 Python 2.6 的安全套接字层（SSL）支持进行了大量改进，通过添加一个新的模块 `ssl`，该模块构建在 OpenSSL 库之上。这个新模块提供了对协商协议、使用的 X.509 证书的更多控制，并更好地支持在 Python 中编写 SSL 服务器（而不是客户端）。`socket` 模块中现有的 SSL 支持没有被移除，继续有效，但将在 Python 3.0 中被移除。

要使用新模块，你必须首先以常规方式创建一个TCP连接，然后将其传递给 `ssl.wrap_socket()` 函数。可以指定是否需要证书，并通过调用 `getpeercert()` 方法获取证书信息。

参见

`ssl` 模块的文档。

## 弃用和移除

- 字符串异常已被移除。尝试使用它们将引发 `TypeError`。

- 根据 PEP 352 的要求，对 `Exception` 接口的更改仍在进行中。对于2.6版本，`message` 属性已被弃用，转而使用 `args` 属性。

- （3.0警告模式）Python 3.0将提供一个重新组织的标准库，该库将删除许多过时的模块并重命名其他模块。在3.0警告模式下运行的Python 2.6将在导入这些模块时发出警告。

  已弃用的模块列表如下：`audiodev`，`bgenlocations`，`buildtools`，`bundlebuilder`，`Canvas`，`compiler`，`dircache`，`dl`，`fpformat`，`gensuitemodule`，`ihooks`，`imageop`，`imgfile`，`linuxaudiodev`，`mhlib`，`mimetools`，`multifile`，`new`，`pure`，`statvfs`，`sunaudiodev`，`test.testall` 和 `toaiff`。

- `gopherlib` 模块已被移除。

- `MimeWriter` 模块和 `mimify` 模块已被弃用；请改用 `email` 包。

- `md5` 模块已被弃用；请改用 `hashlib` 模块。

- `posixfile` 模块已被弃用；`fcntl.lockf()` 可提供更好的锁机制。

- `popen2` 模块已被弃用；请使用 `subprocess` 模块。

- `rgbimg` 模块已被移除。

- `sets` 模块已被弃用；最好使用内置的 `set` 和 `frozenset` 类型。

- `sha` 模块已被弃用；请使用 `hashlib` 模块。

## 构建和 C API 的变更

针对 Python 构建过程和 C API 的变更包括:

- Python现在必须使用C89编译器进行编译（19年后！）。这意味着Python源代码树已删除其自身的 `memmove()` 和 `strerror()` 实现，这些功能在C89标准库中。

- Python 2.6可以使用Microsoft Visual Studio 2008（版本9.0）构建，这也是新的默认编译器。请查看 `PCbuild` 目录以获取构建文件。（由Christian Heimes实现。）

- 在Mac OS X上，Python 2.6可以编译为四路通用构建。configure 脚本可以接受一个 `--with-universal-archs=[32-bit|64-bit|all]` 开关，控制生成的二进制文件是为32位架构（x86，PowerPC）、64位（x86-64和PPC-64）还是两者都支持。（由Ronald Oussoren贡献。）

- 在Python 2.6.6中新增的函数 `PySys_SetArgvEx()`，设置 `sys.argv` 的值，并且可以可选地根据 updatepath 参数的值更新 `sys.path` 以包括包含由 `sys.argv[0]` 指定的脚本的目录。

  此函数的添加是为了关闭嵌入Python的应用程序的安全漏洞。旧的函数 `PySys_SetArgv()` 总是更新 `sys.path`，有时还会添加当前目录。这意味着，如果你在一个由其他人控制的目录中运行嵌入Python的应用程序，攻击者可以在该目录中放置一个木马模块（例如，一个名为 `os.py` 的文件），你的应用程序将会导入并运行它。

  如果你维护一个嵌入Python的C/C++应用程序，检查你是否调用了 `PySys_SetArgv()` 并仔细考虑应用程序是否应该使用 updatepath 设置为false的 `PySys_SetArgvEx()`。请注意，使用此函数将破坏与Python 2.6.5及更早版本兼容性；如果你必须继续使用早期版本，你可以保留对 `PySys_SetArgv()` 的调用，并在之后调用 `PyRun_SimpleString("sys.path.pop(0)\n")` 来丢弃 `sys.path` 的第一个组件。

  安全问题报告为 CVE 2008-5983；在 gh-50003 中讨论，并由Antoine Pitrou修复。

- BerkeleyDB模块现在有一个C API对象，作为 `bsddb.db.api` 提供。这个对象可以被其他希望使用 `bsddb` 模块实现自己目的的C扩展使用。（由Duncan Grisby贡献。）

- 新的缓冲区接口，之前在 PEP 3118 部分 中描述，增加了 `PyObject_GetBuffer()` 和 `PyBuffer_Release()`，以及其他一些函数。

- Python 对 C 标准输入输出库的使用现在是线程安全的，或者至少与底层库一样线程安全。一个长期存在的潜在错误是，如果一个线程在另一个线程正在读取或写入文件对象时关闭该文件对象。在 2.6 版本中，文件对象具有引用计数，由 `PyFile_IncUseCount()` 和 `PyFile_DecUseCount()` 函数操作。文件对象只有在引用计数为零时才能被关闭。`PyFile_IncUseCount()` 应在仍持有 GIL 时调用，在进行使用 `FILE *` 指针的 I/O 操作之前，而 `PyFile_DecUseCount()` 应在重新获取 GIL 后立即调用。（由 Antoine Pitrou 和 Gregory P. Smith 贡献。）

- 在两个不同线程中同时导入模块不再会导致死锁；现在会引发一个 `ImportError`。一个新的 API 函数 `PyImport_ImportModuleNoBlock()`，首先会在 `sys.modules` 中查找模块，然后在获取导入锁后尝试导入它。如果导入锁被另一个线程持有，则会引发 `ImportError`。（由 Christian Heimes 贡献。）

- 有几个函数返回有关平台浮点支持的信息。`PyFloat_GetMax()` 返回最大可表示的浮点值，而 `PyFloat_GetMin()` 返回最小正值。`PyFloat_GetInfo()` 返回一个对象，其中包含来自 `float.h` 文件的更多信息，例如 `"mant_dig"` (尾数中的数字位数) 、`"epsilon"` (1.0 与下一个最大可表示值之间的最小差异) 以及其他几个信息。（由 Christian Heimes 贡献；bpo-1534。）

- 使用 `PyComplex_AsCComplex()` 的 C 函数和方法现在将接受具有 `__complex__()` 方法的参数。特别是，`cmath` 模块中的函数现在将接受具有此方法的对象。这是 Python 3.0 变更的一个回退版本。（由 Mark Dickinson 贡献；bpo-1675423。）

- Python 的 C API 现在包括两个用于不区分大小写的字符串比较函数，`PyOS_stricmp(char*, char*)` 和 `PyOS_strnicmp(char*, char*, Py_ssize_t)`。（由 Christian Heimes 贡献；bpo-1635。）

- 许多 C 扩展在 `init*` 函数中定义了自己的小宏，用于将整数和字符串添加到模块的字典中。Python 2.6 终于定义了用于向模块添加值的标准宏，`PyModule_AddStringMacro` 和 `PyModule_AddIntMacro()`。（由 Christian Heimes 贡献。）

- 一些宏在 3.0 和 2.6 中都被重命名，以更清楚地表明它们是宏，而不是函数。`Py_Size()` 变为 `Py_SIZE()`，`Py_Type()` 变为 `Py_TYPE()`，`Py_Refcnt()` 变为 `Py_REFCNT()`。混合大小写的宏在 Python 2.6 中仍然可用，以保持向后兼容。(bpo-1629)

- Distutils 在运行调试版本的 Python 时，现在将构建的 C 扩展放置在不同的目录中。（由 Collin Winter 贡献；bpo-1530959。）

- 几种基本数据类型，如整数和字符串，维护内部的对象自由列表，这些对象可以重复使用。这些自由列表的数据结构现在遵循命名约定：变量始终命名为 `free_list`，计数器始终命名为 `numfree`，并且始终定义一个宏 `Py<typename>_MAXFREELIST`。

- 一个新的Makefile目标，"make patchcheck"，用于准备Python源代码树以生成补丁：它会修复所有修改过的".py"文件中的尾部空白，检查文档是否已更改，并报告 `Misc/ACKS` 和 `Misc/NEWS` 文件是否已更新。（由 Brett Cannon 贡献。）

  另一个新目标，"make profile-opt"，使用GCC的基于配置的优化来编译Python二进制文件。它会启用配置编译Python，运行测试套件以获取一组配置结果，然后使用这些结果进行优化编译。（由 Gregory P. Smith 贡献。）

### 特定于 Windows 的更改：

- 对Windows 95、98、ME和NT4的支持已被放弃。Python 2.6至少需要Windows 2000 SP4。

- Windows上的新默认编译器是Visual Studio 2008（版本9.0）。Visual Studio 2003（版本7.1）和2005（版本8.0）的构建目录已被移至PC/目录。新的 `PCbuild` 目录支持X64的交叉编译、调试构建和配置引导优化（PGO）。PGO构建比普通构建大约快10%。 （由 Christian Heimes 贡献，Amaury Forgeot d'Arc 和 Martin von Löwis 提供帮助。）

- `msvcrt` 模块现在支持控制台 I/O API 的普通和宽字符变体。`getwch()` 函数读取按键并返回一个 Unicode 值，`getwche()` 函数也是如此。`putwch()` 函数接受一个Unicode字符并将其写入控制台。（由 Christian Heimes 贡献。）

- `os.path.expandvars()` 现在将展开形式为 "%var%"的环境变量，而 "~user" 将被展开为用户的主目录路径。（由 Josiah Carlson 贡献；bpo-957650。）

- `socket` 模块的套接字对象现在有一个 `ioctl()` 方法，它提供了一个有限的接口到 `WSAIoctl()` 系统接口。

- `_winreg` 模块现在有一个函数，`ExpandEnvironmentStrings()`，用于扩展输入字符串中的环境变量引用，如 `%NAME%`。该模块提供的句柄对象现在支持上下文协议，因此可以在 `with` 语句中使用。（由 Christian Heimes 贡献。）

  `_winreg` 还对 x64 系统提供了更好的支持，公开了 `DisableReflectionKey()`、`EnableReflectionKey()` 和 `QueryReflectionKey()` 函数，这些函数用于启用和禁用在 64 位系统上运行的 32 位进程的注册表反射。(bpo-1753245)

- `msilib` 模块的 `Record` 对象增加了 `GetInteger()` 和 `GetString()` 方法，分别返回字段值作为整数或字符串。（由 Floris Bruynooghe 贡献；bpo-2125。）

### 特定于 Mac OS X 的更改：

- 现在，在编译Python的框架版本时，可以为 configure 脚本添加 `--with-framework-name=` 选项来指定要使用的框架名称。

- `macfs` 模块已被移除。这也导致 `macostools.touched()` 函数被移除，因为它依赖于 `macfs` 模块。(bpo-1490190)

- 许多其他 Mac OS 模块已被弃用，并将在 Python 3.0 中移除：`_builtinSuites`、`aepack`、`aetools`、`aetypes`、`applesingle`、`appletrawmain`、`appletrunner`、`argvemulator`、`Audio_mac`、`autoGIL`、`Carbon`、`cfmfile`、`CodeWarrior`、`ColorPicker`、`EasyDialogs`、`Explorer`、`Finder`、`FrameWork`、`findertools`、`ic`、`icglue`、`icopen`、`macerrors`、`MacOS`、`macfs`、`macostools`、`macresource`、`MiniAEFrame`、`Nav`、`Netscape`、`OSATerminology`、`pimp`、`PixMapWrapper`、`StdSuites`、`SystemEvents`、`Terminal` 和 `terminalcommand`。

### 特定于 IRIX 的更改：

一些旧的IRIX特定模块已被弃用，并将在Python 3.0中移除：`al` 和 `AL`，`cd`，`cddb`，`cdplayer`，`CL` 和 `cl`，`DEVICE`，`ERRNO`，`FILE`，`FL` 和 `fl`，`flp`，`fm`，`GET`，`GLWS`，`GL` 和 `gl`，`IN`，`IOCTL`，`jpeg`，`panelparser`，`readcd`，`SV` 和 `sv`，`torgb`，`videoreader`，以及 `WAIT`。

## 移植到Python 2.6

本节列出了先前描述的改变以及可能需要修改你的代码的其他问题修正:

- 预期为不可哈希的类应当在其定义中设置 `__hash__ = None` 来指明这一点。

- 字符串异常已被移除。尝试使用它们将引发 `TypeError`。

- `collections.deque` 的 `__init__()` 方法现在会在从可迭代对象添加元素之前清空deque中的任何现有内容。这一改变使得其行为与 `list.__init__()` 相匹配。

- 以前 `object.__init__()` 接受任意参数和关键字参数，并忽略它们。在Python 2.6中，这不再被允许，并将导致 `TypeError`。这将影响最终调用 `object` 上相应方法（可能通过使用 `super()`）的 `__init__()` 方法。参见 bpo-1683368 进行讨论。

- `Decimal` 构造函数现在在接受字符串时允许前导和尾随空格。以前它会引发 `InvalidOperation` 异常。另一方面，`Context` 对象的 `create_decimal()` 方法现在明确禁止额外空格，并引发 `ConversionSyntax` 异常。

- 由于实现上的意外，如果你将文件路径传递给内置的 `__import__()` 函数，它实际上会导入指定的文件。这从未打算工作，然而，现在的实现明确检查这种情况并引发 `ImportError`。

- C API：`PyImport_Import()` 和 `PyImport_ImportModule()` 函数现在默认为绝对导入，而不是相对导入。这将影响导入其他模块的C扩展。

- C API：不应可哈希的扩展数据类型应将其 `tp_hash` 插槽定义为 `PyObject_HashNotImplemented()`。

- `socket` 模块的异常 `socket.error` 现在继承自 `IOError`。以前它不是 `StandardError` 的子类，但现在通过 `IOError` 继承了。（由 Gregory P. Smith 实现；bpo-1706815。）

- `xmlrpclib` 模块不再自动将 `datetime.date` 和 `datetime.time` 转换为 `xmlrpclib.DateTime` 类型；转换语义并不一定适用于所有应用。使用 `xmlrpclib` 的代码应转换 `date` 和 `time` 实例。（bpo-1330538）

- (3.0 警告模式) `Exception` 类在被切片或索引访问时会产生警告。`Exception` 像元组一样的行为正在被逐步淘汰。

- （3.0 警告模式）两个字典或两个未实现比较方法的对象之间的不等比较会被报告为警告。`dict1 == dict2` 仍然有效，但 `dict1 < dict2` 正在被逐步淘汰。

  单元格之间的比较，这是 Python 作用域规则的实现细节，也会导致警告，因为在 3.0 中完全禁止此类比较。

对于嵌入Python的应用程序：

- Python 2.6.6 中增加了 `PySys_SetArgvEx()` 函数，这让应用可以弥补一个在使用现有 `PySys_SetArgv()` 函数时会存在的安全漏洞。 请检查你是否有调用 `PySys_SetArgv()` 并仔细考虑应用是否应当改用 `PySys_SetArgvEx()` 并将 updatepath 设为假值。

## 致谢

作者感谢以下人员对本文各种草稿给予的建议，更正和协助： Georg Brandl、Steve Brown、Nick Coghlan、Ralph Corderoy、Jim Jewett、Kent Johnson、Chris Lambacher、 Martin Michlmayr、Antoine Pitrou、Brian Warner。