python 3.0的新功能¶
- 作者
吉多·范罗苏姆
本文解释了与2.6相比,python 3.0中的新特性。python 3.0,也称为“python 3000”或“py3k”,是有史以来第一个 故意向后不相容 python版本。有比典型版本更多的更改,对所有的Python用户来说更重要。不过,在消化了这些变化之后,您会发现python实际上并没有改变那么多——大体上,我们主要是修复众所周知的烦恼和疣,并去除许多旧的拐杖。
本文并不试图提供所有新特性的完整规范,而是试图提供一个方便的概述。有关完整的详细信息,您应该参考Python3.0的文档和/或本文中引用的许多PEP。如果您想了解特定功能的完整实现和设计原理,PEPS通常比常规文档有更多的细节;但是请注意,一旦功能完全实现,PEPS通常不会保持最新。
由于时间限制,此文档没有本应的那么完整。像往常一样,对于新版本, Misc/NEWS
源发行版中的文件包含了关于每一个被更改的小东西的大量详细信息。
常见的绊脚石¶
如果您习惯于Python2.5,本节将列出最有可能使您陷入困境的少数更改。
Print 是一个函数¶
这个 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!
注:
视图和迭代器而不是列表¶
一些著名的API不再返回列表:
dict
方法dict.keys()
,dict.items()
和dict.values()
返回“视图”而不是列表。例如,这不再有效:k = d.keys(); k.sort()
. 使用k = sorted(d)
相反(这也适用于Python2.5,而且效率也一样高)。此外,
dict.iterkeys()
,dict.iteritems()
和dict.itervalues()
不再支持方法。map()
和filter()
返回迭代器。如果您真的需要一个列表,并且输入序列的长度都是相等的,那么一个快速的解决方法就是封装map()
在里面list()
,例如list(map(...))
但更好的解决方法通常是使用列表理解(尤其是当原始代码使用lambda
或者重写代码,使其完全不需要列表。特别棘手的是map()
为函数的副作用调用;正确的转换是使用正则for
循环(因为创建列表是浪费)。如果输入序列的长度不相等,
map()
将在最短序列结束时停止。完全兼容map()
在python 2.x中,还将序列封装在itertools.zip_longest()
,例如map(func, *sequences)
变成list(map(func, itertools.zip_longest(*sequences)))
.range()
现在表现得像xrange()
用于行为,但用于任意大小的值。后者已不复存在。zip()
现在返回迭代器。
排序比较¶
python 3.0简化了排序比较规则:
排序比较运算符 (
<
,<=
,>=
,>
)当操作数没有有意义的自然顺序时引发类型错误异常。因此,表达式1 < ''
,0 > None
或len <= len
不再有效,例如None < None
引发TypeError
而不是返回False
. 一个推论是,对异类列表进行排序不再有意义——所有元素都必须相互比较。请注意,这不适用于==
和!=
运算符:不同不可比类型的对象总是比较不相等。builtin.sorted()
和list.sort()
不再接受 cmp 提供比较函数的参数。而是使用 key 参数。N.B. 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
以获取截断行为。(后一种语法已经存在很多年了,至少从Python2.2开始是这样。)这个
sys.maxint
常量被删除,因为整数的值不再有限制。然而,sys.maxsize
可以用作大于任何实际列表或字符串索引的整数。它符合实现的“自然”整数大小,并且通常与sys.maxint
在同一平台上的早期版本中(假设有相同的构建选项)。这个
repr()
长整数的不包括尾随L
因此,无条件地删除该字符的代码将切掉最后一个数字。(使用)str()
取而代之的是)八进制文字不再是这种形式
0720
使用0o720
相反。
文本与数据而不是Unicode与8位¶
关于二进制数据和Unicode的所有知识都已经改变了。
python 3.0使用了 text 和(二进制) data 而不是Unicode字符串和8位字符串。所有文本都是Unicode;但是 编码的 Unicode表示为二进制数据。用于保存文本的类型是
str
,用于保存数据的类型是bytes
. 与2.x情况的最大区别在于,在Python3.0中混合文本和数据的任何尝试都会引发TypeError
,而如果在python 2.x中混合使用unicode和8位字符串,那么如果8位字符串恰好只包含7位(ascii)字节,那么它就可以工作,但是UnicodeDecodeError
如果它包含非ASCII值。这些年来,这种特定于价值观的行为引起了无数的悲伤。由于这种理念的改变,几乎所有使用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
, thebytes
类型不可变。有一个单独的 易变的 保存缓冲二进制数据的类型,bytearray
. 几乎所有接受的APIbytes
也接受bytearray
. 可变API基于collections.MutableSequence
.原始字符串文本中的所有反斜杠都是逐字解释的。这意味着
'\U'
和'\u'
原始字符串中的转义不进行特殊处理。例如,r'\u20ac'
是Python3.0中由6个字符组成的字符串,而在2.6中,ur'\u20ac'
是唯一的“欧元”字符。(当然,此更改只影响原始字符串文本;欧元字符是'\u20ac'
在Python 3中)。内置的
basestring
抽象类型已删除。使用str
相反。这个str
和bytes
类型没有足够的共同功能来保证共享的基类。这个2to3
工具(见下文)将替换basestring
具有str
.作为文本文件打开的文件(仍然是
open()
)始终使用编码在字符串(内存中)和字节(磁盘上)之间进行映射。二进制文件(用b
在模式参数中)总是使用内存中的字节。这意味着,如果使用不正确的模式或编码打开一个文件,I/O可能会很大声地失败,而不是静默地生成不正确的数据。这还意味着,即使是UNIX用户在打开文件时也必须指定正确的模式(文本或二进制)。有一个依赖于平台的默认编码,在Unixy平台上可以使用LANG
环境变量(有时还与其他特定于平台的语言环境相关的环境变量一起使用)。在许多情况下,但不是所有情况下,系统默认值都是UTF-8;您不应该指望这个默认值。任何读或写超过纯ASCII文本的应用程序都应该有一种重写编码的方法。不再需要在codecs
模块。sys.stdin
,sys.stdout
和sys.stderr
的初始值 现在是纯Unicode文本文件(即,它们是io.TextIOBase
)要使用这些流读取和写入字节数据,需要使用io.TextIOBase.buffer
属性。文件名作为(Unicode)字符串传递给API并从API返回。这可能会出现平台特定的问题,因为在某些平台上,文件名是任意字节字符串。(另一方面,在Windows上,文件名本机存储为Unicode。)作为解决方案,大多数API(例如
open()
以及os
模块)接受文件名bytes
对象和字符串,以及一些API有一种方法来请求bytes
返回值。因此,os.listdir()
返回的列表bytes
如果参数是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 WHOTO 更新了python 3.0。
语法更改概述¶
本节简要概述了 句法的 更改python 3.0。
新语法¶
PEP 3107 :函数参数和返回值注释。这提供了一种标准化的方法来注释函数的参数和返回值。除了可以在运行时使用
__annotations__
属性。其目的是鼓励通过元类、修饰器或框架进行实验。PEP 3102 :仅关键字参数。命名参数出现在
*args
在参数列表中 must 在调用中使用关键字语法指定。您也可以使用裸机*
在参数列表中指示您不接受变长参数列表,但您确实有只包含关键字的参数。类定义中的基类列表后允许使用关键字参数。这被新的约定用于指定元类(参见下一节),但也可以用于其他目的,只要元类支持它。
PEP 3104 :
nonlocal
语句。使用nonlocal x
现在可以直接分配给外部(但不是全局)范围中的变量。nonlocal
是一个新的保留字。PEP 3132 :扩展ITerable解包。你现在可以写
a, b, *rest = some_sequence
. 甚至*rest, a = stuff
. 这个rest
对象始终是一个(可能是空的)列表;右侧可以是任何一个iterable。例子::(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()
构造函数,尤其是循环控制变量不再泄漏到周围的范围中。这个 省略 (
...
)可以在任何地方用作原子表达式。(以前只允许切片)另外,它 must 现在拼写为...
. (以前也可以拼写为. . .
只是语法上的意外。)
删除语法¶
PEP 3113 :t已移除元组参数解包。你不能再写了
def foo(a, (b, c)): ...
. 使用def foo(a, b_c): b, c = b_c
相反。删除的背景(使用
repr()
相反)。弃用
<>
(使用)!=
相反)。删除的关键字:
exec()
不再是关键字;它仍然是一个函数。(幸运的是,函数语法在2.x中也被接受。)还要注意exec()
不再采用流参数;而不是exec(f)
你可以用exec(f.read())
.整数文本不再支持尾随
l
或L
.字符串文本不再支持前导
u
或U
.相对导入唯一可接受的语法是
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__
. 也签出 编写上下文管理器 和 ContextLib模块 .PEP 366:从主模块显式的相对导入 . 这提高了
-m
当引用的模块位于包中时的选项。PEP 3101:高级字符串格式 . 注:2.6描述提到
format()
用于8位和Unicode字符串的方法。在3.0中,只有str
类型(支持Unicode的文本字符串)支持此方法;该bytes
类型没有。该计划最终将使其成为字符串格式的唯一API,并开始对%
python 3.1中的运算符。PEP 3105: print 作为一个函数 . 这现在是标准功能,不再需要从导入
__future__
. 以上给出了更多细节。PEP 3110:异常处理更改 . 这个
except
excas
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 和 特洛夫德 . 还要注意,一个无效的 mode 现在参数起来了ValueError
不是IOError
. 文本文件对象的基础二进制文件对象可以访问为f.buffer
(但请注意,为了加快编码和解码操作,文本对象保持自身的缓冲区)。PEP 3118:修订的缓冲协议 .旧的内建帐户
buffer()
现在真的不见了;新的内建帐户memoryview()
提供(大部分)类似的功能。PEP 3119:抽象基类 . 这个
abc
模块和ABC在collections
模块现在在语言中的作用更加突出,内置的集合类型如dict
和list
符合collections.MutableMapping
和collections.MutableSequence
分别是ABC。PEP 3127:整数文本支持和语法 . 如上所述,新的八进制文字符号是唯一支持的符号,并且已经添加了二进制文字。
PEP 3141:数字的类型层次结构 . 这个
numbers
模块是abcs的另一个新用途,定义了python的“数字塔”。还要注意新的fractions
实现的模块numbers.Rational
.
类库变革¶
由于时间限制,本文档并未完全涵盖对标准库所做的非常广泛的更改。 PEP 3108 是对库的主要更改的引用。以下是Capsules评论:
许多旧模块被移除。一些,像
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
温雷格
ConfigParser
配置分析器
copy_reg
复印件
排队
队列
SocketServer
socketserver
标记库
_markupbase
再PR
瑞普利布
test.test_support
test.support
python 2.x中的一个常见模式是使用纯python实现一个模块的一个版本,可选的加速版本作为C扩展实现;例如,
pickle
和cPickle
. 这就增加了导入加速版本的负担,并使这些模块的每个用户都回到纯Python版本上。在Python3.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()
应用程序编程接口。这个
new
模块消失了。功能
os.tmpnam()
,os.tempnam()
和os.tmpfile()
已被移除以支持tempfile
模块。这个
tokenize
模块已更改为使用字节。现在主要的入口点是tokenize.tokenize()
,而不是生成令牌。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}
. 此外,您不能再显式地指定回溯;相反,如果 have 为此,您可以直接将__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__()
.
Builtins¶
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()
. 而不是apply(f, args)
使用f(*args)
.弃用
callable()
. 而不是callable(f)
你可以用isinstance(f, collections.Callable)
. 这个operator.isCallable()
功能也消失了。弃用
coerce()
. 由于经典类已不复存在,此函数不再起作用。弃用
execfile()
. 而不是execfile(fn)
使用exec(open(fn).read())
.弃用
reduce()
. 使用functools.reduce()
如果你真的需要它;但是,99%的时候for
循环更可读。弃用
reload()
. 使用imp.reload()
.弃用。
dict.has_key()
--使用in
而不是操作员。
构建和C API更改¶
由于时间限制,以下是 very 对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
.弃用
METH_OLDARGS
和WITH_CYCLE_GC
从C API。
性能¶
3.0归纳的最终结果是,python 3.0运行pystone基准比python 2.5慢10%左右。最可能的最大原因是移除了小整数的特殊大小写。还有改进的空间,但在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
源代码树上的源到源转换器。(见 2to 3-自动python 2到3代码转换 有关此工具的更多信息。)在python 3.0下运行转换结果。手动修复所有剩余问题,修复问题,直到所有测试再次通过。
不建议尝试编写在python 2.6和3.0下运行不变的源代码;您必须使用非常扭曲的编码样式,例如避免 print
语句、元类等等。如果您维护的库需要同时支持python 2.6和python 3.0,那么最好的方法是通过编辑源代码的2.6版本并运行 2to3
再次转换,而不是编辑源代码的3.0版本。
要将C扩展移植到python 3.0,请参见 将扩展模块移植到python 3 .