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"。

参见:

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


开发过程的变化
==============

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


新问题追踪器：Roundup
---------------------

很长一段时间以来，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程序可以创建新进程来执行计算并返回结
果给父进程。父进程和子进程可以使用队列和管道进行通信，使用锁和信号量同
步它们的操作，并且可以共享简单的数据数组。

"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" 将创建固
定数量的工作进程，然后可以通过调用 "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'

参见:

  Format string syntax
     格式字段的参考文档。

  **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" 值，这两个值将分别是结果分数的
分子和分母。

   >>> from fractions import 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 as dt

   # 创建数据结构
   data_struct = dict(lastAccessed=dt.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。
