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 中不受支持的用法。
标准库中添加了一些重要的新包,例如 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 需要多少工作。此开关的值可通过布尔变量 sys.py3kwarning
在 Python 代码中获取,并通过 Py_Py3kWarningFlag
在 C 扩展代码中获取。
开发流程的变更¶
在 2.6 开发期间,Python 开发流程经历了两次重大变更:我们从 SourceForge 的问题追踪器切换到定制的 Roundup 安装,并且文档从 LaTeX 转换为 reStructuredText。
新问题追踪器:Roundup¶
很长一段时间以来,Python 开发人员对 SourceForge 的 bug 跟踪器越来越感到恼火。SourceForge 的托管解决方案不允许进行太多自定义;例如,无法自定义问题的生命周期。
因此,Python 软件基金会的基础设施委员会发布了征集问题跟踪器的请求,要求志愿者设置不同的产品并从 SourceForge 导入一些错误和补丁。检查了四种不同的跟踪器:Jira、Launchpad、Roundup 和 Trac。委员会最终选择了 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 作为其文档工具。
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__()
方法仍然会被调用,但 type、value 和 traceback 都为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__()
方法是最复杂的,因为大部分工作必须在这里完成。该方法必须检查是否发生了异常。如果没有异常,事务将被提交。如果发生异常,事务将被回滚。
在下面的代码中,执行将直接跳出函数末尾,返回默认值 None
。None
为假,因此异常将自动重新抛出。如果您愿意,可以更明确地在标记位置添加一个 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
,父进程和子进程可以使用该对象进行通信。(如果父进程更改全局变量的值,子进程的值将不受影响,反之亦然。)
另外两个类,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):
"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 文档;这里是一些示例
|
二进制。以 2 为基数输出数字。 |
|
字符。在打印前将整数转换为相应的 Unicode 字符。 |
|
十进制整数。以 10 为基数输出数字。 |
|
八进制格式。以 8 为基数输出数字。 |
|
十六进制格式。以 16 为基数输出数字,9 以上的数字使用小写字母。 |
|
指数表示法。以科学记数法打印数字,使用字母“e”表示指数。 |
|
通用格式。这会将数字打印为定点数,除非数字太大,在这种情况下它会切换到“e”指数表示法。 |
|
数字。这与“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 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!
...
作者可能试图捕获 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 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
属性,用于保存底层的原始对象。有五个实现此抽象基类的具体类。
BufferedWriter
和BufferedReader
用于支持只写或只读用法且具有用于随机访问的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 参数指定了对返回内存的约束。一些示例如下
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 支持包括一个 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)
检查对象是否为数字而存在。
Complex
是 Number
的子类。复数可以进行加法、减法、乘法、除法和乘方等基本操作,并且您可以检索实部和虚部并获取复数的共轭。Python 的内置 complex 类型是 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
,它们是装饰器,为现有属性添加 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-8
或 latin-1
;可选的 errorhandler 部分指定如何处理编码无法处理的字符,应为“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”)的 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-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') >>> # 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()
方法现在返回一个具有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 贡献。)# 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()
方法现在返回一个具有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 贡献。)如果使用了 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.HTTPConnection
和HTTPSConnection
类构造函数中添加了一个可选的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
类及其子类WatchedFileHandler
、RotatingFileHandler
和TimedRotatingFileHandler
现在其构造函数中有一个可选的 delay 参数。如果 delay 为 True,则日志文件的打开将延迟到第一次调用emit()
时进行。(由 Vinay Sajip 贡献。)TimedRotatingFileHandler
也有一个 utc 构造函数参数。如果该参数为 True,则在确定午夜发生时间和生成文件名时将使用 UTC 时间;否则将使用本地时间。math
模块中添加了几个新函数: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。)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()
函数,该函数接受一个名称和一组可选参数,返回一个可调用对象,该对象将在传递给它的任何参数上调用命名函数。例如:>>> # 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)
有效地关闭从 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 位系统上进行 pickled,并在 64 位系统上进行 unpickled,反之亦然。不幸的是,这一变化也意味着 Python 2.6 的Random
对象不能在早期版本的 Python 上正确地 unpickled。(由 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
模块现在有 Linuxepoll()
和 BSDkqueue()
系统调用的包装函数。现有的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)
新的
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") # ... 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。
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
属性;如果为 True,则异常和格式化的回溯将作为 HTTP 头部“X-Exception”和“X-Traceback”返回。此功能仅用于调试目的,不应用于生产服务器,因为回溯可能会泄露密码或其他敏感信息。(由 Alan McIntyre 作为他 2007 年 Google Summer of Code 项目的一部分贡献。)xmlrpclib
模块不再自动将datetime.date
和datetime.time
转换为xmlrpclib.DateTime
类型;这种转换语义不一定适用于所有应用程序。使用xmlrpclib
的代码应该转换date
和time
实例。(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
该模块还包括 NodeVisitor
和 NodeTransformer
类,用于遍历和修改 AST,以及用于常见转换(如更改行号)的函数。
future_builtins
模块¶
Python 3.0 对内置函数库进行了许多更改,其中大多数更改无法在 Python 2.x 系列中引入,因为它们会破坏兼容性。future_builtins
模块提供了这些内置函数的版本,可以在编写 3.0 兼容代码时导入。
此模块中的函数目前包括
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.testall
和toaiff
。gopherlib
模块已被删除。MimeWriter
模块和mimify
模块已弃用;请改用email
包。md5
模块已弃用;请改用hashlib
模块。posixfile
模块已弃用;fcntl.lockf()
提供了更好的锁定。popen2
模块已弃用;请改用subprocess
模块。rgbimg
模块已被删除。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_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)在调试版本的 Python 上运行时,Distutils 现在将其构建的 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。)_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 的应用程序
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。