Python 2.6 的新特性

作者:

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

本文解释了 Python 2.6 的新功能,该版本于 2008 年 10 月 1 日发布。发布时间表在PEP 361中描述。

Python 2.6 的主要主题是为迁移到 Python 3.0 做准备,3.0 是对语言的重大重新设计。只要有可能,Python 2.6 会整合 3.0 的新功能和语法,同时通过不删除旧功能或语法来保持与现有代码的兼容性。当无法做到这一点时,Python 2.6 会尽力而为,在 future_builtins 模块中添加兼容性函数,并添加 -3 开关来警告将在 3.0 中不受支持的用法。

标准库中添加了一些重要的新包,例如 multiprocessingjson 模块,但与 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 需要多少工作。此开关的值可通过布尔变量 sys.py3kwarning 在 Python 代码中获取,并通过 Py_Py3kWarningFlag 在 C 扩展代码中获取。

参见

3xxx 系列的 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 导入一些错误和补丁。检查了四种不同的跟踪器:JiraLaunchpadRoundupTrac。委员会最终选择了 Jira 和 Roundup 作为两个候选者。Jira 是一种商业产品,为免费软件项目提供免费托管实例;Roundup 是一个开源项目,需要志愿者来管理它并需要服务器来托管它。

在发布志愿者招募后,一个新的 Roundup 安装在 https://bugs.python.org 建立。一个 Roundup 安装可以托管多个追踪器,现在这个服务器也托管 Jython 和 Python 网站的问题追踪器。它将来肯定会找到其他用途。在可能的情况下,此版本的“Python 新功能”会链接到每个更改的 bug/补丁项。

Python bug 跟踪器的托管由南非斯泰伦博斯(Stellenbosch)的 Upfront Systems 友情提供。Martin von Löwis 在从 SourceForge 导入现有 bug 和补丁方面付出了大量努力;他的导入操作脚本位于 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://sphinx-doc.cn/ 获取。

Sphinx 专注于 HTML 输出,生成美观时尚的 HTML;通过转换为 LaTeX 仍然支持打印输出。输入格式是 reStructuredText,一种支持自定义扩展和指令的标记语法,在 Python 社区中常用。

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

参见

记录 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
        ... more processing code ...

该语句执行后,f 中的文件对象将自动关闭,即使 for 循环在块执行中途抛出异常。

备注

在这种情况下,f 是由 open() 创建的同一对象,因为 __enter__() 返回 self

threading 模块的锁和条件变量也支持“with”语句

lock = threading.Lock()
with lock:
    # Critical section of code
    ...

锁在块执行前被获取,并在块完成后始终释放。

decimal 模块中的 localcontext() 函数使得保存和恢复当前十进制上下文变得容易,它封装了计算所需的精度和舍入特性

from decimal import Decimal, Context, localcontext

# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()

with localcontext(Context(prec=16)):
    # All code in this block uses a precision of 16 digits.
    # The original context is restored on exiting the block.
    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__() 方法仍然会被调用,但 typevaluetraceback 都为 None

让我们来看一个例子。我不会提供详细的代码,只会粗略地介绍支持事务的数据库所需的方法。

(对于不熟悉数据库术语的人:对数据库的一组更改被分组到事务中。事务可以被提交,这意味着所有更改都写入数据库,或者被回滚,这意味着所有更改都被丢弃,数据库保持不变。有关更多信息,请参阅任何数据库教科书。)

假设有一个代表数据库连接的对象。我们的目标是让用户编写如下代码

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... more operations ...

如果块中的代码运行完美,事务应该被提交;如果出现异常,事务应该被回滚。这是我将假定的 DatabaseConnection 的基本接口

class DatabaseConnection:
    # Database interface
    def cursor(self):
        "Returns a cursor object and starts a new transaction"
    def commit(self):
        "Commits current transaction"
    def rollback(self):
        "Rolls back current transaction"

__enter__() 方法非常简单,只需开始一个新事务。对于此应用程序,生成的游标对象将是一个有用的结果,因此该方法将返回它。用户随后可以向其“with”语句添加 as cursor,将游标绑定到变量名。

class DatabaseConnection:
    ...
    def __enter__(self):
        # Code to start a new transaction
        cursor = self.cursor()
        return cursor

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

在下面的代码中,执行将直接跳出函数末尾,返回默认值 NoneNone 为假,因此异常将自动重新抛出。如果您愿意,可以更明确地在标记位置添加一个 return 语句。

class DatabaseConnection:
    ...
    def __exit__(self, type, value, tb):
        if tb is None:
            # No exception, so commit
            self.commit()
        else:
            # Exception occurred, so rollback.
            self.rollback()
            # return 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):
    "Compute a factorial."
    # If N is a multiple of 4, this function will take much longer.
    if (N % 4) == 0:
        time.sleep(.05 * N/4)

    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Put the result on the queue
    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,父进程和子进程可以使用该对象进行通信。(如果父进程更改全局变量的值,子进程的值将不受影响,反之亦然。)

另外两个类,PoolManager,提供更高级别的接口。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):
    "Compute a factorial."
    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Store result in dictionary
    dictionary[N] = fact

if __name__ == '__main__':
    p = Pool(5)
    mgr = Manager()
    d = mgr.dict()         # Create shared dictionary

    # Run tasks using the pool
    for N in range(1, 1000, 10):
        p.apply_async(factorial, (N, d))

    # Mark pool as closed -- no more tasks can be added.
    p.close()

    # Wait for tasks to exit
    p.join()

    # Output results
    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() 方法,它将字符串视为模板并获取要格式化的参数。格式化模板使用花括号 ({, }) 作为特殊字符

>>> # Substitute positional argument 0 into the string.
>>> "User ID: {0}".format("root")
'User ID: root'
>>> # Use the named keyword arguments
>>> "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 作为键来查找值。以数字开头的字符串将转换为整数。您不能在格式字符串中编写更复杂的表达式。

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

>>> # Field 0: left justify, pad to 15 characters
>>> # Field 1: right justify, pad to 6 characters
>>> 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 由 Talin 编写。由 Eric 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:  # Wrong!
    ...

作者可能试图捕获 TypeErrorValueError 异常,但这段代码实际上做了不同的事情:它会捕获 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 位字节;您现在可以使用 bytesstr 来精确表示您的意图,并且生成的代码在 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 characters

在 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 编写;由 Christian Heimes 回溯到 2.6。

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 属性,用于保存底层的原始对象。

    有五个实现此抽象基类的具体类。BufferedWriterBufferedReader 用于支持只写或只读用法且具有用于随机访问的 seek() 方法的对象。BufferedRandom 对象支持在同一底层流上进行读写访问,而 BufferedRWPair 用于诸如 TTY 等对象,它们在不相关的数据流上执行读写操作。BytesIO 类支持在内存缓冲区上进行读、写和查找。

  • TextIOBase:提供用于读写字符串的函数(记住,在 Python 3.0 中,字符串将是 Unicode),并支持通用换行符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 参数指定了对返回内存的约束。一些示例如下

PyArg_ParseTuple() 的两个新参数代码 s*z*,返回参数的锁定缓冲区对象。

参见

PEP 3118 - 修订缓冲区协议

PEP 由 Travis Oliphant 和 Carl Banks 编写;由 Travis Oliphant 实现。

PEP 3119: 抽象基类

一些面向对象语言,如 Java,支持接口,声明一个类具有一组给定的方法或支持给定的访问协议。抽象基类(或 ABC)是 Python 的等效功能。AB​​C 支持包括一个 abc 模块,其中包含一个名为 ABCMeta 的元类,内置的 isinstance()issubclass() 对此元类进行特殊处理,以及 Python 开发人员认为将广泛有用的一系列基本 ABC。未来的 Python 版本可能会添加更多的 ABC。

假设您有一个特定的类,并且希望知道它是否支持字典风格的访问。“字典风格”这个词是模糊的。它可能意味着用 obj[1] 访问项目有效。它是否意味着用 obj[2] = value 设置项目有效?或者对象将有 keys()values()items() 方法?迭代变体,如 iterkeys() 呢?copy`和 :meth:()!update`?用 iter() 迭代对象呢?

Python 2.6 的 collections 模块包含许多不同的 ABC,它们代表这些区别。Iterable 表示一个类定义了 __iter__(),而 Container 意味着该类定义了 __contains__() 方法,因此支持 x in y 表达式。获取项目、设置项目以及 keys()values()items() 的基本字典接口由 MutableMapping ABC 定义。

您可以从特定的 ABC 派生自己的类,以表明它们支持该 ABC 的接口

import collections

class Storage(collections.MutableMapping):
    ...

或者,您可以不从所需的 ABC 派生类,而是通过调用 ABC 的 register() 方法来注册类

import collections

class Storage:
    ...

collections.MutableMapping.register(Storage)

对于您编写的类,从 ABC 派生可能更清晰。当您编写了一个新的 ABC,可以描述现有类型或类,或者您想声明某个第三方类实现了某个 ABC 时,register() 方法很有用。例如,如果您定义了一个 PrintableType ABC,那么执行以下操作是合法的

# Register Python's types
PrintableType.register(int)
PrintableType.register(float)
PrintableType.register(str)

类应遵守 ABC 指定的语义,但 Python 无法检查这一点;这取决于类作者理解 ABC 的要求并相应地实现代码。

要检查对象是否支持特定接口,您现在可以编写

def func(d):
    if not isinstance(d, collections.MutableMapping):
        raise ValueError("Mapping object expected, not %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 和 Alex Martelli 反向移植到 2.6。

PEP 3127: 整数字面量支持和语法

Python 3.0 改变了八进制(base-8)整数字面量的语法,用“0o”或“0O”而不是前导零作为前缀,并增加了对二进制(base-2)整数字面量的支持,以“0b”或“0B”前缀表示。

Python 2.6 并没有放弃对前导 0 表示八进制数字的支持,但它确实增加了对“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”前缀,当请求 base-8 或 base-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) 检查对象是否为数字而存在。

ComplexNumber 的子类。复数可以进行加法、减法、乘法、除法和乘方等基本操作,并且您可以检索实部和虚部并获取复数的共轭。Python 的内置 complex 类型是 Complex 的一个实现。

Real 进一步派生自 Complex,并添加了只作用于实数的操作:floor()trunc()、舍入、取模 N 的余数、地板除法和比较。

Rational 数字派生自 Real,具有 numeratordenominator 属性,并且可以转换为浮点数。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。但是,此逻辑不应应用于 KeyboardInterruptSystemExit;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 实现。)

  • 属性现在有三个属性:gettersetterdeleter,它们是装饰器,为现有属性添加 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')  # Intersection between all inputs
    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(),如果其浮点参数是无穷大或非数字,则返回 True。(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 冲刺的工作,struct 模块中的所有函数都已用 C 语言重写。(由 Raymond Hettinger 贡献。)

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

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

  • 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 环境变量来指定标准输入、输出和标准错误使用的编码。该值应为 <encoding><encoding>:<errorhandler> 形式的字符串。encoding 部分指定编码名称,例如 utf-8latin-1;可选的 errorhandler 部分指定如何处理编码无法处理的字符,应为“error”、“ignore”或“replace”之一。(由 Martin von Löwis 贡献。)

新增和改进的模块

与每个版本一样,Python 的标准库也获得了许多增强和错误修复。以下是按模块名称字母顺序排序的最值得注意的更改的部分列表。有关更完整的更改列表,请查阅源代码树中的 Misc/NEWS 文件,或查看 Subversion 日志以获取所有详细信息。

  • asyncoreasynchat 模块再次积极维护,并应用了许多补丁和错误修复。(由 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”)的 URL 进行表单操作。(由 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-1381asinh()atanh()atan() 的分支割也已更正。

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

    在 IEEE 754 平台上,cmath 模块现在以与 C99 标准附件“G”一致的方式处理 IEEE 754 特殊值和浮点异常。

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

    >>> var_type = collections.namedtuple('variable',
    ...             'id name type size')
    >>> # Names are separated by spaces or commas.
    >>> # 'id, name, type, size' would also work.
    >>> var_type._fields
    ('id', 'name', 'type', 'size')
    
    >>> var = var_type(1, 'frequency', 'int', 4)
    >>> print var[0], var.id    # Equivalent
    1 1
    >>> print var[2], var.type  # Equivalent
    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() 方法现在返回一个具有 signdigitsexponent 字段的命名元组。

    (由 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 贡献。)

    # Boldface text starting at y=0,x=21
    # and affecting the rest of the line.
    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() 方法现在返回一个具有 signdigitsexponent 字段的命名元组。

    (由 Facundo Batista 和 Mark Dickinson 实现。命名元组支持由 Raymond Hettinger 添加。)

  • difflib 模块的 SequenceMatcher 类现在返回表示匹配的命名元组,具有 absize 属性。(由 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 贡献。)

  • 如果使用了 Unicode 路径并且目录中匹配了 Unicode 文件名,则 glob.glob() 函数现在可以返回 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 贡献。)

  • httplib.HTTPConnectionHTTPSConnection 类构造函数中添加了一个可选的 timeout 参数,指定以秒为单位的超时时间。(由 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]) 返回 iterable 元素的长度为 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 类及其子类 WatchedFileHandlerRotatingFileHandlerTimedRotatingFileHandler 现在其构造函数中有一个可选的 delay 参数。如果 delay 为 True,则日志文件的打开将延迟到第一次调用 emit() 时进行。(由 Vinay Sajip 贡献。)

    TimedRotatingFileHandler 也有一个 utc 构造函数参数。如果该参数为 True,则在确定午夜发生时间和生成文件名时将使用 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-711019bpo-1640。)

    (由 Christian Heimes 和 Mark Dickinson 贡献。)

  • mmap 对象现在有一个 rfind() 方法,该方法从字符串末尾开始向后搜索子字符串。find() 方法也获得了一个 end 参数,用于指定停止搜索的索引。(由 John Lenton 贡献。)

  • operator 模块获得了一个 methodcaller() 函数,该函数接受一个名称和一组可选参数,返回一个可调用对象,该对象将在传递给它的任何参数上调用命名函数。例如:

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

    (由 Georg Brandl 贡献,源于 Gregory Petrosyan 的建议。)

    attrgetter() 函数现在接受点分名称并执行相应的属性查找。

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

    (由 Georg Brandl 贡献,源于 Barry Warsaw 的建议。)

  • 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) 有效地关闭从 lowhigh 的所有文件描述符,忽略任何错误且不包括 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 位系统上进行 pickled,并在 64 位系统上进行 unpickled,反之亦然。不幸的是,这一变化也意味着 Python 2.6 的 Random 对象不能在早期版本的 Python 上正确地 unpickled。(由 Shawn Ligocki 贡献;bpo-1727780。)

    新的 triangular(low, high, mode) 函数返回遵循三角形分布的随机数。返回的值在 lowhigh 之间,不包括 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 样式模式,并返回一个可调用对象,该对象将忽略与这些模式中的任何一个匹配的文件和目录。以下示例复制目录树,但跳过 .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 在代理之间传输电子邮件时使用,这些代理不管理邮件队列。(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 文件。如果此变量为 True,则不写入编译后的文件。该变量在启动时通过向 Python 解释器提供 -B 开关,或在运行解释器之前设置 PYTHONDONTWRITEBYTECODE 环境变量来初始化设置。Python 代码随后可以更改此变量的值,以控制是否写入字节码文件。(由 Neal Norwitz 和 Georg Brandl 贡献。)

    有关提供给 Python 解释器的命令行参数的信息可通过读取 sys.flags 中可用命名元组的属性获得。例如,如果 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) tarfile。默认格式是 GNU tar;使用 format 参数指定以不同格式打开文件

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

    新的 encodingerrors 参数指定了字符转换的编码和错误处理方案。'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 贡献。)

    NamedTemporaryFileSpooledTemporaryFile 类都作为上下文管理器工作,因此您可以编写 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")
        # ... code that triggers a warning ...
        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。)

  • 由 Gregor Lingl 大幅增强了海龟绘图模块 turtle。该模块的新功能包括

    • 更好的海龟移动和旋转动画。

    • 使用新的 delay()tracer()speed() 方法控制海龟运动。

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

    • 海龟现在有一个 undo() 方法,可以回滚操作。

    • 对鼠标和键盘活动等输入事件做出反应的简单支持,从而可以编写简单的游戏。

    • turtle.cfg 文件可用于自定义海龟屏幕的起始外观。

    • 模块的 docstrings 可以替换为已翻译成其他语言的新 docstrings。

    (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 SimpleXMLRPCServerDocXMLRPCServer 类现在可以通过将 False 作为 bind_and_activate 构造函数参数来阻止它们立即打开并绑定到其套接字。这可用于在调用 server_bind()server_activate() 方法以打开套接字并开始侦听连接之前修改实例的 allow_reuse_address 属性。(由 Peter Parente 贡献;bpo-1599845。)

    SimpleXMLRPCServer 还有一个 _send_traceback_header 属性;如果为 True,则异常和格式化的回溯将作为 HTTP 头部“X-Exception”和“X-Traceback”返回。此功能仅用于调试目的,不应用于生产服务器,因为回溯可能会泄露密码或其他敏感信息。(由 Alan McIntyre 作为他 2007 年 Google Summer of Code 项目的一部分贡献。)

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

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

    z = zipfile.ZipFile('python-251.zip')
    
    # Unpack a single file, writing it relative
    # to the /tmp directory.
    z.extract('Python/sysmodule.c', '/tmp')
    
    # Unpack all the files in the archive.
    z.extractall()
    

    (由 Alan McIntyre 贡献;bpo-467924。)

    open()read()extract() 方法现在可以接受文件名或 ZipInfo 对象。当存档中意外包含重复文件名时,这非常有用。(由 Graham Horler 贡献;bpo-1775025。)

    最后,zipfile 现在支持使用 Unicode 文件名进行存档文件。(由 Alexey Borzenkov 贡献;bpo-1734346。)

ast 模块

ast 模块提供了 Python 代码的抽象语法树表示,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

该模块还包括 NodeVisitorNodeTransformer 类,用于遍历和修改 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): 这些版本不会调用 __hex__()__oct__() 方法,而是调用 __index__() 方法并将结果转换为十六进制或八进制。oct() 将使用新的 0o 符号表示其结果。

json 模块:JavaScript 对象表示法

新的 json 模块支持在 JSON (Javascript Object Notation) 中编码和解码 Python 类型。JSON 是一种轻量级交换格式,常用于 Web 应用程序。有关 JSON 的更多信息,请参阅 http://www.json.org

json 支持解码和编码大多数内置 Python 类型。以下示例编码和解码一个字典

>>> import json
>>> data = {"spam": "foo", "parrot": 42}
>>> in_json = json.dumps(data) # Encode the data
>>> in_json
'{"parrot": 42, "spam": "foo"}'
>>> json.loads(in_json) # Decode into a Python object
{"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

# Create data structure
data_struct = dict(lastAccessed=datetime.datetime.now(),
                   version=1,
                   categories=('Personal','Shared','Private'))

# Create string containing XML.
plist_str = plistlib.writePlistToString(data_struct)
new_struct = plistlib.readPlistFromString(plist_str)
print data_struct
print new_struct

# Write data structure to a file and read it back.
plistlib.writePlist(data_struct, '/tmp/customizations.plist')
new_struct = plistlib.readPlist('/tmp/customizations.plist')

# read/writePlist accepts file-like objects as well as paths.
plistlib.writePlist(data_struct, sys.stdout)

ctypes 增强功能

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

ctypes 现在支持表示 C99 bool 类型的 c_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 通过添加一个新模块 ssl,该模块构建在 OpenSSL 库之上,从而对 Python 2.6 的安全套接字层支持进行了广泛改进。这个新模块提供了对协商协议、使用的 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.testalltoaiff

  • gopherlib 模块已被删除。

  • MimeWriter 模块和 mimify 模块已弃用;请改用 email 包。

  • md5 模块已弃用;请改用 hashlib 模块。

  • posixfile 模块已弃用;fcntl.lockf() 提供了更好的锁定。

  • popen2 模块已弃用;请改用 subprocess 模块。

  • rgbimg 模块已被删除。

  • sets 模块已弃用;最好使用内置的 setfrozenset 类型。

  • 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 可以编译为 4 向通用构建。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 stdio 库的使用现在是线程安全的,或者至少与底层库一样线程安全。如果一个线程关闭文件对象而另一个线程正在读取或写入该对象,则会发生一个长期存在的潜在错误。在 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_AddStringMacroPyModule_AddIntMacro()。(由 Christian Heimes 贡献。)

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

  • 在调试版本的 Python 上运行时,Distutils 现在将其构建的 C 扩展放置在不同的目录中。(由 Collin Winter 贡献;bpo-1530959。)

  • 几个基本数据类型,例如整数和字符串,维护内部可重用对象的空闲列表。这些空闲列表的数据结构现在遵循命名约定:变量始终命名为 free_list,计数器始终命名为 numfree,并且始终定义宏 Py<typename>_MAXFREELIST

  • 一个新的 Makefile 目标,“make patchcheck”,准备 Python 源代码树以制作补丁:它修复所有修改过的 .py 文件中的尾随空格,检查文档是否已更改,并报告 Misc/ACKSMisc/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 中移除:_builtinSuitesaepackaetoolsaetypesapplesingleappletrawmainappletrunnerargvemulatorAudio_macautoGILCarboncfmfileCodeWarriorColorPickerEasyDialogsExplorerFinderFrameWorkfindertoolsicicglueicopenmacerrorsMacOSmacfsmacostoolsmacresourceMiniAEFrameNavNetscapeOSATerminologypimpPixMapWrapperStdSuitesSystemEventsTerminalterminalcommand

特定于端口的更改:IRIX

一些旧的 IRIX 特定模块已被弃用,并将在 Python 3.0 中移除:alALcdcddbcdplayerCLclDEVICEERRNOFILEFLflflpfmGETGLWSGLglINIOCTLjpegpanelparserreadcdSVsvtorgbvideoreaderWAIT

移植到 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.datedatetime.time 转换为 xmlrpclib.DateTime 类型;这种转换语义不一定适用于所有应用程序。使用 xmlrpclib 的代码应转换 datetime 实例。( bpo-1330538 )

  • (3.0-警告模式) Exception 类现在在使用切片或索引访问时发出警告;使 Exception 表现得像一个元组正在逐步淘汰。

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

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

适用于嵌入 Python 的应用程序

  • PySys_SetArgvEx() 函数在 Python 2.6.6 中添加,允许应用程序在使用现有 PySys_SetArgv() 函数时关闭一个安全漏洞。检查您是否正在调用 PySys_SetArgv() 并仔细考虑应用程序是否应使用 updatepath 设置为 false 的 PySys_SetArgvEx()

致谢

作者要感谢以下人员为本文的各种草稿提供了建议、更正和帮助:Georg Brandl、Steve Brown、Nick Coghlan、Ralph Corderoy、Jim Jewett、Kent Johnson、Chris Lambacher、Martin Michlmayr、Antoine Pitrou、Brian Warner。