Python 3.0 的新特性 — Python 文档
Python 3.0 中的新功能
- 作者
- 吉多·范罗苏姆
本文解释了 Python 3.0 中与 2.6 相比的新特性。 Python 3.0,也称为“Python 3000”或“Py3K”,是有史以来第一个 故意向后不兼容 Python 版本。 与典型版本相比,有更多的更改,并且对所有 Python 用户来说更重要的更改。 尽管如此,在消化了这些变化之后,您会发现 Python 确实没有发生太大的变化——总的来说,我们主要是修复众所周知的烦恼和缺陷,并删除了很多旧的问题。
本文并不试图提供所有新功能的完整规范,而是试图提供一个方便的概述。 有关完整的详细信息,您应该参考 Python 3.0 的文档和/或文本中引用的许多 PEP。 如果您想了解特定功能的完整实现和设计原理,PEP 通常比常规文档包含更多详细信息; 但请注意,一旦功能完全实现,PEP 通常不会保持最新。
由于时间限制,本文档没有应有的完整。 与新版本一样,源代码分发中的 Misc/NEWS
文件包含有关更改的每个小事情的大量详细信息。
常见的绊脚石
如果您习惯了 Python 2.5,本节列出了最有可能让您感到困惑的少数更改。
打印是一种功能
print
语句已替换为 print() 函数,使用关键字参数替换旧的 print
语句( ]PEP 3105)。 例子:
Old: print "The answer is", 2*2
New: print("The answer is", 2*2)
Old: print x, # Trailing comma suppresses newline
New: print(x, end=" ") # Appends a space instead of a newline
Old: print # Prints a newline
New: print() # You must call the function!
Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)
Old: print (x, y) # prints repr((x, y))
New: print((x, y)) # Not the same as print(x, y)!
您还可以自定义项目之间的分隔符,例如:
print("There are <", 2**32, "> possibilities!", sep="")
它产生:
There are <4294967296> possibilities!
笔记:
- print() 函数不支持旧的
print
语句的“软空间”功能。 例如,在 Python 2.x 中,print "A\n", "B"
会写成"A\nB\n"
; 但在 Python 3.0 中,print("A\n", "B")
写为"A\n B\n"
。 - 最初,您会发现自己在交互模式下经常输入旧的
print x
。 是时候重新训练您的手指来输入print(x)
了! - 使用
2to3
源到源转换工具时,所有print
语句都会自动转换为 print() 函数调用,因此这对于更大的项目。
视图和迭代器而不是列表
一些著名的 API 不再返回列表:
dict 方法 dict.keys(), dict.items() 和 dict.values() 返回“视图”而不是列表. 例如,这不再有效:
k = d.keys(); k.sort()
。 使用k = sorted(d)
代替(这也适用于 Python 2.5 并且同样有效)。此外,不再支持
dict.iterkeys()
、dict.iteritems()
和dict.itervalues()
方法。map() 和 filter() 返回迭代器。 如果你真的需要一个列表并且输入序列的长度都相等,一个快速的解决方法是将 map() 包裹在 list() 中,例如
list(map(...))
,但更好的解决方法通常是使用列表推导式(尤其是当原始代码使用 lambda 时),或者重写代码使其根本不需要列表。 特别棘手的是 map() 为函数的副作用而调用; 正确的转换是使用常规的 for 循环(因为创建列表只会浪费)。如果输入序列的长度不相等,map() 将在最短序列的终止处停止。 为了与 Python 2.x 中的 map() 完全兼容,还将序列包装在 itertools.zip_longest() 中,例如
map(func, *sequences)
变为list(map(func, itertools.zip_longest(*sequences)))
。range() 现在的行为类似于
xrange()
以前的行为,除了它适用于任意大小的值。 后者已不复存在。zip() 现在返回一个迭代器。
订购比较
Python 3.0 简化了排序比较的规则:
- 当操作数没有有意义的自然排序时,排序比较运算符(
<
、<=
、>=
、>
)会引发 TypeError 异常。 因此,像1 <
、0 > None
或len <= len
这样的表达式不再有效,例如None < None
引发 TypeError 而不是返回False
。 一个推论是对异构列表进行排序不再有意义——所有元素必须相互比较。 请注意,这不适用于==
和!=
运算符:不同不可比较类型的对象总是相互不相等。 builtin.sorted()
和 list.sort() 不再接受提供比较函数的 cmp 参数。 请改用 key 参数。 NB key 和 reverse 参数现在是“仅关键字”。cmp()
函数应该被视为消失了,并且不再支持__cmp__()
特殊方法。 使用__lt__()
进行排序,__eq__()
与__hash__()
,以及其他需要的丰富比较。 (如果您确实需要cmp()
功能,您可以使用表达式(a > b) - (a < b)
作为cmp(a, b)
的等价物。)
整数
- PEP 237:本质上,
long
重命名为 int。 也就是说,只有一种内置整数类型,名为 int; 但它的行为主要类似于旧的long
类型。 - PEP 238:像
1/2
这样的表达式返回一个浮点数。 使用1//2
获得截断行为。 (后一种语法已经存在多年,至少从 Python 2.2 开始是这样。) sys.maxint
常量被删除,因为不再有整数值的限制。 但是,sys.maxsize 可以用作比任何实际列表或字符串索引都大的整数。 它符合实现的“自然”整数大小,并且通常与同一平台上以前版本中的sys.maxint
相同(假设相同的构建选项)。- 长整数的 repr() 不再包含尾随的
L
,因此无条件去除该字符的代码将截断最后一位数字。 (使用 str() 代替。) - 八进制文字不再是
0720
的形式; 改用0o720
。
文字对比 数据而不是 Unicode Vs。 8 位
你认为你知道的关于二进制数据和 Unicode 的一切都发生了变化。
- Python 3.0 使用 text 和(二进制)data 的概念,而不是 Unicode 字符串和 8 位字符串。 所有文本都是Unicode; 然而 encoded Unicode 表示为二进制数据。 用来保存文本的类型是str,用来保存数据的类型是bytes。 与 2.x 情况的最大区别在于,任何在 Python 3.0 中混合文本和数据的尝试都会引发 TypeError,而如果您要在 Python 2.x 中混合使用 Unicode 和 8 位字符串,则会出现如果 8 位字符串碰巧只包含 7 位 (ASCII) 字节,则可以工作,但如果它包含非 ASCII 值,则会得到 UnicodeDecodeError。 多年来,这种特定于价值的行为引起了无数悲伤的面孔。
- 由于这种理念上的变化,几乎所有使用 Unicode、编码或二进制数据的代码很可能都必须更改。 这种变化是为了更好的,因为在 2.x 世界中有许多错误与混合编码和未编码的文本有关。 要在 Python 2.x 中做好准备,开始对所有未编码文本使用
unicode
,仅对二进制或编码数据使用 str。 然后2to3
工具将为您完成大部分工作。 - 您不能再将
u"..."
文字用于 Unicode 文本。 但是,您必须对二进制数据使用b"..."
文字。 - 由于 str 和 bytes 类型不能混合使用,您必须始终在它们之间进行显式转换。 使用 str.encode() 从 str 到 bytes,使用 bytes.decode() 从 bytes 到 str。 您也可以分别使用
bytes(s, encoding=...)
和str(b, encoding=...)
。 - 与 str 一样,bytes 类型是不可变的。 有一个单独的 mutable 类型来保存缓冲的二进制数据,bytearray。 几乎所有接受 bytes 的 API 也接受 bytearray。 可变 API 基于
collections.MutableSequence
。 - 原始字符串文字中的所有反斜杠都按字面解释。 这意味着未对原始字符串中的
'\U'
和'\u'
转义进行特殊处理。 例如,r'\u20ac'
在 Python 3.0 中是 6 个字符的字符串,而在 2.6 中,ur'\u20ac'
是单个“欧元”字符。 (当然,此更改仅影响原始字符串文字;欧元字符在 Python 3.0 中为'\u20ac'
。) - 内置的
basestring
抽象类型已被删除。 请改用 str。 str 和 bytes 类型没有足够的共同功能来保证共享基类。2to3
工具(见下文)用 str 替换每次出现的basestring
。 - 作为文本文件打开的文件(仍然是 open() 的默认模式)总是使用编码在字符串(内存中)和字节(磁盘上)之间进行映射。 二进制文件(在 mode 参数中用
b
打开)总是使用内存中的字节。 这意味着如果使用不正确的模式或编码打开文件,I/O 可能会大声失败,而不是默默地产生不正确的数据。 这也意味着即使是 Unix 用户在打开文件时也必须指定正确的模式(文本或二进制)。 有一个平台相关的默认编码,在 Unixy 平台上可以使用LANG
环境变量(有时也可以使用其他一些特定于平台的语言环境相关的环境变量)进行设置。 在很多情况下,但不是全部,系统默认是 UTF-8; 你永远不应该指望这个默认值。 任何读取或写入比纯 ASCII 文本更多的应用程序都应该有办法覆盖编码。 不再需要在 codecs 模块中使用编码感知流。 - sys.stdin、sys.stdout 和 sys.stderr 的初始值现在是 unicode-only 文本文件(即,它们是 的实例) io.TextIOBase)。 要使用这些流读取和写入字节数据,您需要使用它们的 io.TextIOBase.buffer 属性。
- 文件名作为 (Unicode) 字符串传递给 API 并从 API 返回。 这可能会出现特定于平台的问题,因为在某些平台上文件名是任意字节字符串。 (另一方面,在 Windows 上,文件名本机存储为 Unicode。)作为一种变通方法,大多数 API(例如 open() 和 os 模块中的许多函数)接受文件名接受 bytes 对象以及字符串,并且一些 API 有方法要求bytes 返回值。 因此,如果参数是 bytes 实例,os.listdir() 返回 bytes 实例的列表,并且 os.getcwdb() ] 将当前工作目录作为 bytes 实例返回。 请注意,当 os.listdir() 返回字符串列表时,无法正确解码的文件名将被省略,而不是引发 UnicodeError。
- 当系统提供的可用字节无法使用默认编码进行解释时,某些系统 API(如 os.environ 和 sys.argv)也会出现问题。 设置
LANG
变量并重新运行程序可能是最好的方法。 - PEP 3138:字符串的 repr() 不再转义非 ASCII 字符。 但是,它仍然会转义 Unicode 标准中具有不可打印状态的控制字符和代码点。
- PEP 3120:默认源编码现在是 UTF-8。
- PEP 3131:现在允许在标识符中使用非 ASCII 字母。 (但是,除了注释中的贡献者姓名外,标准库仍然是仅 ASCII 格式的。)
StringIO
和cStringIO
模块不见了。 相反,导入 io 模块并分别对文本和数据使用 io.StringIO 或 io.BytesIO。- 另请参阅 Unicode HOWTO,它已针对 Python 3.0 进行了更新。
语法更改概述
本节简要概述了 Python 3.0 中的每个 语法 更改。
新语法
PEP 3107:函数参数和返回值注释。 这提供了注释函数参数和返回值的标准化方法。 除了可以在运行时使用
__annotations__
属性自省之外,此类注释没有附加语义。 目的是鼓励通过元类、装饰器或框架进行实验。PEP 3102:仅关键字参数。 在参数列表 中出现在
*args
之后的命名参数必须在调用中使用关键字语法指定。 您还可以在参数列表中使用一个空*
来表示您不接受可变长度的参数列表,但您确实有仅关键字参数。在类定义中的基类列表之后允许使用关键字参数。 这被新约定用于指定元类(参见下一节),但也可用于其他目的,只要元类支持它。
PEP 3104:非本地 语句。 使用
nonlocal x
您现在可以直接分配给外部(但非全局)范围内的变量。nonlocal
是新的保留字。PEP 3132:扩展迭代解包。 您现在可以编写诸如
a, b, *rest = some_sequence
之类的内容。 甚至*rest, a = stuff
。rest
对象总是一个(可能是空的)列表; 右侧可以是任何可迭代的。 例子:(a, *rest, b) = range(5)
这会将 a 设置为
0
,将 b 设置为4
,并将 rest 设置为[1, 2, 3]
。字典推导:
{k: v for k, v in stuff}
与dict(stuff)
意思相同,但更灵活。 (这是 PEP 274 平反。 :-)设置文字,例如
{1, 2}
。 注意{}
是一个空字典; 使用set()
作为空集。 还支持集合理解; 例如,{x for x in stuff}
与set(stuff)
的含义相同,但更灵活。新的八进制文字,例如
0o720
(已在 2.6 中)。 旧的八进制文字 (0720
) 消失了。新的二进制文字,例如
0b1010
(已经在2.6中),并且有一个新的对应内置函数,bin()。字节文字以
b
或B
开头,并且有一个新的对应内置函数,bytes()。
更改语法
PEP 3109 和 PEP 3134:新的 raise 语句语法:
raise [expr [from expr]]
。 见下文。as
和 with 现在是保留字。 (实际上从 2.6 开始。)True
、False
和None
是保留字。 (2.6 已经部分强制执行了对None
的限制。)PEP 3115:新的元类语法。 代替:
class C: __metaclass__ = M ...
你现在必须使用:
class C(metaclass=M): ...
不再支持模块全局
__metaclass__
变量。 (这是一个拐杖,它可以更容易地默认为新型类,而无需从 object 派生每个类。)列表推导式不再支持语法形式
[... for var in item1, item2, ...]
。 请改用[... for var in (item1, item2, ...)]
。 另请注意,列表推导式具有不同的语义:它们更接近于 list() 构造函数内的生成器表达式的语法糖,尤其是循环控制变量不再泄漏到周围的作用域中。省略号 (
...
) 可以在任何地方用作原子表达式。 (以前它只允许在切片中。)此外,它 必须 现在拼写为...
。 (以前它也可以拼写为. . .
,这仅仅是语法上的一个意外。)
删除的语法
- PEP 3113:删除元组参数解包。 你不能再写
def foo(a, (b, c)): ...
。 请改用def foo(a, b_c): b, c = b_c
。 - 删除了反引号(改用 repr())。
- 移除了
<>
(改为使用!=
)。 - 移除关键字:exec() 不再是关键字; 它仍然是一个函数。 (幸运的是,2.x 中也接受了函数语法。)还要注意 exec() 不再接受流参数; 您可以使用
exec(f.read())
代替exec(f)
。 - 整数文字不再支持尾随
l
或L
。 - 字符串文字不再支持前导
u
或U
。 - from module import
*
语法只允许在模块级别,不再在函数内部。 - 相对导入唯一可接受的语法是
from .[module] import name
。 所有不以.
开头的 import 形式都被解释为绝对导入。 (PEP 328) - 经典课没了。
Python 2.6 中已经存在的变化
由于许多用户可能直接从 Python 2.5 跳转到 Python 3.0,因此本节提醒读者最初为 Python 3.0 设计但后来移植到 Python 2.6 的新功能。 应查阅 Python 2.6 中的新增功能 中的相应部分以获得更长的描述。
- PEP 343:'with' 语句 。 with 语句现在是标准功能,不再需要从 __future__ 导入。 另请查看 编写上下文管理器 和 上下文库模块 。
- PEP 366:来自主模块的显式相对导入 。 当引用的模块位于包中时,这增强了 -m 选项的实用性。
- PEP 370:每用户站点包目录 。
- PEP 371:多处理包。
- PEP 3101:高级字符串格式 。 注意:2.6 描述中提到了 8 位和 Unicode 字符串的 format() 方法。 在 3.0 中,只有 str 类型(支持 Unicode 的文本字符串)支持此方法; bytes 类型没有。 计划最终使其成为字符串格式化的唯一 API,并开始弃用 Python 3.1 中的
%
运算符。 - PEP 3105:作为函数打印。 这现在是标准功能,不再需要从 __future__ 导入。 上面给出了更多细节。
- PEP 3110:异常处理更改 。 except exc
as
var 语法现在是标准语法,except
exc, 不再支持 var。 (当然,as
var 部分仍然是可选的。) - PEP 3112:字节文字。
b"..."
字符串文字符号(及其变体,如b'...'
、b"""..."""
和br"..."
)现在生成 bytes 类型的文字. - PEP 3116:新的 I/O 库 。 io 模块现在是执行文件 I/O 的标准方式。 内置的 open() 函数现在是 io.open() 的别名,并且有额外的关键字参数 encoding、errors , newline 和 closefd。 另请注意,无效的 mode 参数现在引发 ValueError,而不是 IOError。 文本文件对象下的二进制文件对象可以作为
f.buffer
访问(但要注意,文本对象维护自己的缓冲区以加快编码和解码操作)。 - PEP 3118:修订缓冲协议 。 旧的内置
buffer()
现在真的不见了; 新的内置 memoryview() 提供(大部分)类似的功能。 - PEP 3119:抽象基类 。 abc 模块和定义在 collections 模块中的 ABC 现在在语言中扮演着更为突出的角色,内置的集合类型如 dict 和 [ X191X]list 分别符合
collections.MutableMapping
和collections.MutableSequence
ABC。 - PEP 3127:整数文字支持和语法 。 如上所述,新的八进制文字表示法是唯一受支持的,并且添加了二进制文字。
- PEP 3129:类装饰器 。
- PEP 3141:数字 的类型层次结构。 numbers 模块是 ABC 的另一个新用途,定义了 Python 的“数字塔”。 还要注意新的 fractions 模块,它实现了 numbers.Rational。
图书馆变化
由于时间限制,本文档没有详尽地涵盖对标准库的非常广泛的更改。 PEP 3108 是对库的主要更改的参考。 这是一个胶囊评论:
许多旧模块被删除。 一些,如
gopherlib
(不再使用)和md5
(由 hashlib 取代),已经被 PEP 4 弃用]。 由于取消了对 Irix、BeOS 和 Mac OS 9 等各种平台的支持(请参阅 PEP 11),其他部分被删除。 由于缺乏使用或因为存在更好的替代品,一些模块也被选择在 Python 3.0 中删除。 有关详尽列表,请参阅 PEP 3108。bsddb3
包被删除,因为随着时间的推移,由于测试的不稳定性和 Berkeley DB 的发布时间表,它在核心标准库中的存在已被证明是核心开发人员的一个特殊负担。 但是,该软件包仍然有效,外部维护在 https://www.jcea.es/programacion/pybsddb.htm。一些模块被重命名是因为它们的旧名称违反了 PEP 8,或者其他各种原因。 这是清单:
旧名
新名字
_winreg
温格
配置解析器
配置解析器
复制注册表
复制注册表
队列
队列
套接字服务器
套接字服务器
标记库
_标记库
代表
复制库
test.test_support
测试支持
Python 2.x 中的一个常见模式是用纯 Python 实现模块的一个版本,以及作为 C 扩展实现的可选加速版本; 例如,pickle 和
cPickle
。 这给这些模块的每个用户带来了导入加速版本和使用纯 Python 版本的负担。 在 Python 3.0 中,加速版本被视为纯 Python 版本的实现细节。 用户应该始终导入标准版本,它会尝试导入加速版本并回退到纯 Python 版本。 pickle /cPickle
对接受了这种处理。 profile 模块在 3.1 的列表中。StringIO
模块已经变成了io模块中的一个类。一些相关的模块已被分组到包中,通常子模块名称已被简化。 由此产生的新包是:
PEP 3108 未涵盖的对标准库模块的一些其他更改:
- 杀死
sets
。 使用内置的 set() 类。 - sys 模块的清理:移除
sys.exitfunc()
、sys.exc_clear()
、sys.exc_type
、sys.exc_value
、sys.exc_traceback
。 (注意 sys.last_type 等。 保持。) - array.array 类型的清理:
read()
和write()
方法消失了; 改用fromfile()
和tofile()
。 此外,数组的'c'
类型代码也消失了——使用'b'
表示字节或'u'
表示 Unicode 字符。 - operator 模块的清理:移除了
sequenceIncludes()
和isCallable()
。 thread
模块的清理:acquire_lock()
和release_lock()
不见了; 改用acquire()
和release()
。- random 模块的清理:删除了
jumpahead()
API。 new
模块不见了。- 功能
os.tmpnam()
、os.tempnam()
和os.tmpfile()
已被移除,以支持 tempfile 模块。 - tokenize 模块已更改为使用字节。 主要入口点现在是 tokenize.tokenize(),而不是 generate_tokens。
string.letters
和它的朋友(string.lowercase
和string.uppercase
)不见了。 使用 string.ascii_letters 等。 反而。 (删除的原因是string.letters
和朋友有特定于语言环境的行为,这对于这些名字很吸引人的全局“常量”来说是个坏主意。)- 将模块
__builtin__
重命名为 builtins(删除下划线,添加一个“s”)。 大多数全局命名空间中的__builtins__
变量没有改变。 要修改内置函数,您应该使用 builtins,而不是__builtins__
!
PEP 3101:一种新的字符串格式化方法
- 内置字符串格式化操作的新系统取代了
%
字符串格式化操作符。 (但是,仍然支持%
运算符;它将在 Python 3.1 中被弃用,并在稍后从语言中删除。)阅读 PEP 3101全勺。
对异常的更改
用于引发和捕获异常的 API 已被清理,并添加了新的强大功能:
PEP 352:所有异常都必须(直接或间接)从 BaseException 派生。 这是异常层次结构的根。 这不是新的建议,但从 BaseException 继承的 要求 是新的。 (Python 2.6 仍然允许引发经典类,并且没有限制您可以捕获的内容。)因此,字符串异常终于真正彻底地消亡了。
几乎所有的异常实际上都应该从 Exception 派生出来; BaseException 仅应用作仅应在顶层处理的异常的基类,例如 SystemExit 或 KeyboardInterrupt。 处理除后一类之外的所有异常的推荐习惯用法是使用 except Exception。
StandardError
被移除。异常不再表现为序列。 请改用
args
属性。PEP 3109:引发异常。 您现在必须使用
raise Exception(args)
而不是raise Exception, args
。 此外,您不能再明确指定回溯; 相反,如果您 有 来执行此操作,您可以直接分配给__traceback__
属性(见下文)。PEP 3110:捕获异常。 您现在必须使用
except SomeException as variable
而不是except SomeException, variable
。 此外,当保留 except 块时,会显式删除 变量 。PEP 3134:异常链。 有两种情况:隐式链接和显式链接。 当在 except 或 finally 处理程序块中引发异常时,会发生隐式链接。 这通常是由于处理程序块中的错误而发生的; 我们称之为 次要 异常。 在这种情况下,原始异常(正在处理的)被保存为次要异常的
__context__
属性。 使用以下语法调用显式链接:raise SecondaryException() from primary_exception
(其中 primary_exception 是任何产生异常对象的表达式,可能是先前捕获的异常)。 在这种情况下,主要异常存储在次要异常的
__cause__
属性中。 发生未处理的异常时打印的回溯遍历__cause__
和__context__
属性链,并为链的每个组件打印单独的回溯,主要异常位于顶部。 (Java 用户可能会认识到这种行为。)PEP 3134:异常对象现在将其回溯存储为
__traceback__
属性。 这意味着异常对象现在包含与异常有关的所有信息,并且使用 sys.exc_info() 的理由更少(尽管后者没有被删除)。当 Windows 无法加载扩展模块时,改进了一些异常消息。 例如,
error code 193
现在是%1 is not a valid Win32 application
。 字符串现在处理非英语语言环境。
杂项其他更改
运算符和特殊方法
!=
现在返回与==
相反的结果,除非==
返回 NotImplemented。- “未绑定方法”的概念已从语言中删除。 将方法作为类属性引用时,您现在会得到一个普通的函数对象。
__getslice__()
、__setslice__()
和__delslice__()
被杀。 语法a[i:j]
现在转换为a.__getitem__(slice(i, j))
(或__setitem__()
或__delitem__()
,分别用作分配或删除目标时)。- PEP 3114:标准的 next() 方法已重命名为 __next__()。
__oct__()
和__hex__()
特殊方法被删除 - oct() 和 hex() 现在使用__index__()
来转换参数为整数。- 删除了对
__members__
和__methods__
的支持。 - 名为
func_X
的函数属性已重命名为使用__X__
形式,在函数属性命名空间中为用户定义的属性释放了这些名称。 即,func_closure
、func_code
、func_defaults
、func_dict
、func_doc
、func_globals
、func_name
] 重命名为__closure__
、__code__
、__defaults__
、__dict__、__doc__
、__globals__
__name__,分别。 __nonzero__()
现在是__bool__()
。
内置函数
- PEP 3135:新的 super()。 您现在可以不带参数调用 super() 并且(假设这是在 class 语句中定义的常规实例方法中)将自动选择正确的类和实例。 使用参数,super() 的行为不变。
- PEP 3111:
raw_input()
重命名为 input()。 也就是说,新的 input() 函数从 sys.stdin 中读取一行,并在删除尾随换行符的情况下返回它。 如果输入过早终止,它会引发 EOFError。 要获得 input() 的旧行为,请使用eval(input())
。 - 添加了一个新的内置函数 next() 来调用对象的 __next__() 方法。
- round() 函数舍入策略和返回类型已更改。 确切的中途情况现在四舍五入到最接近的偶数结果,而不是远离零。 (例如,
round(2.5)
现在返回2
而不是3
。)round(x[, n])
现在委托给x.__round__([n])
而不是总是返回一个浮点数。 它通常在使用单个参数调用时返回一个整数,在使用两个参数调用时返回与x
相同类型的值。 - 将
intern()
移至 sys.intern()。 - 移除:
apply()
。 使用f(*args)
代替apply(f, args)
。 - 删除了 callable()。 您可以使用
isinstance(f, collections.Callable)
代替callable(f)
。operator.isCallable()
功能也没有了。 - 移除
coerce()
。 既然经典类已经消失,这个函数就不再有用了。 - 移除
execfile()
。 使用exec(open(fn).read())
代替execfile(fn)
。 - 移除了
file
类型。 使用 open()。 现在有几种不同类型的流可以在 io 模块中返回。 - 移除
reduce()
。 如果确实需要,请使用 functools.reduce(); 然而,在 99% 的情况下,显式的 for 循环更具可读性。 - 移除
reload()
。 使用 imp.reload()。 - 已移除。
dict.has_key()
– 改用 in 运算符。
构建和 C API 更改
由于时间限制,这里有一个 非常 不完整的 C API 更改列表。
- 取消了对多个平台的支持,包括但不限于 Mac OS 9、BeOS、RISCOS、Irix 和 Tru64。
- PEP 3118:新的缓冲区 API。
- PEP 3121 :扩展模块初始化和终结。
- PEP 3123:使PyObject_HEAD符合标准C。
- 不再为受限执行提供 C API 支持。
PyNumber_Coerce()
、PyNumber_CoerceEx()
、PyMember_Get()
和PyMember_Set()
C API 被删除。- 新的 C API PyImport_ImportModuleNoBlock(),与 PyImport_ImportModule() 类似,但不会阻塞导入锁(而是返回错误)。
- 重命名布尔转换 C 级插槽和方法:
nb_nonzero
现在是nb_bool
。 - 从 C API 中删除了
METH_OLDARGS
和WITH_CYCLE_GC
。
表现
3.0 泛化的最终结果是 Python 3.0 运行 pystone 基准测试大约比 Python 2.5 低 10% s。 最有可能的最大原因是删除了小整数的特殊情况。 有改进的空间,但会在 3.0 发布后发生!
移植到 Python 3.0
要将现有的 Python 2.5 或 2.6 源代码移植到 Python 3.0,最佳策略如下:
(先决条件:)从出色的测试覆盖率开始。
移植到 Python 2.6。 这应该不会比从 Python 2.x 到 Python 2.(x+1) 的平均端口更多的工作。 确保所有测试都通过。
(仍在使用2.6:)打开
-3
命令行开关。 这会启用有关将在 3.0 中删除(或更改)的功能的警告。 再次运行您的测试套件,并修复您收到警告的代码,直到没有警告为止,并且您的所有测试仍然通过。在源代码树上运行
2to3
源到源转换器。 (有关此工具的更多信息,请参阅 2to3 - 自动 Python 2 到 3 代码翻译。)在 Python 3.0 下运行翻译结果。 手动修复任何剩余的问题,修复问题直到所有测试再次通过。
不建议尝试编写在 Python 2.6 和 3.0 下都运行不变的源代码; 你必须使用非常扭曲的编码风格,例如 避免 print
语句、元类等等。 如果您正在维护一个需要同时支持 Python 2.6 和 Python 3.0 的库,最好的方法是通过编辑 2.6 版本的源代码并再次运行 2to3
转换器来修改上面的第 3 步,而不是编辑3.0 版本的源代码。
有关将 C 扩展移植到 Python 3.0,请参阅 将扩展模块移植到 Python 3。