python / 3.7.2rc1 / all / whatsnew-3.0.html

Python 3.0 的新增Function

  • Author

    • 吉多·范·罗苏姆(Guido van Rossum)

本文介绍了与 2.6 相比,Python 3.0 的新Function。 Python 3.0,也称为“ Python 3000”或“ Py3K”,是第一个故意向后不兼容的 Python 版本。与典型发行版相比,存在更多的更改,而这些更改对于所有 Python 用户而言都非常重要。不过,在消化了这些变化之后,您会发现 Python 并没有 true 改变太多-总的来说,我们主要是在修复众所周知的烦恼和弊端,并删除了许多旧的东西。

本文不try提供所有新Function的完整规范,而是try提供方便的概述。有关完整的详细信息,您应该参考 Python 3.0 的文档和/或文本中引用的许多 PEP。如果您想了解特定Function的完整实现和设计原理,PEP 通常比常规文档提供更多详细信息。但请注意,一旦Function完全实现,PEP 通常就不会保持最新状态。

由于时间限制,本文档不如应有的完整。与新版本一样,源代码发行版中的Misc/NEWS文件包含大量有关更改的每件事的详细信息。

常见绊脚石

如果您习惯使用 Python 2.5,本部分列出了一些最有可能使您失望的更改。

打印是一种Function

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="")

which produces:

There are <4294967296> possibilities!

Note:

视图和迭代器而不是列表

一些知名的 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()返回迭代器。如果您确实需要一个列表并且 Importing 序列的长度都相等,则快速解决方案是将map()包装在list()中,例如list(map(...)),但是更好的解决方案通常是使用列表理解(尤其是当原始代码使用lambda时),或者重写代码以使其根本不需要列表。 map()为函数的副作用而特别棘手;正确的转换是使用常规的for循环(因为创建列表将很浪费)。

如果 Importing 序列的长度不相等,则map()将在最短序列的终止处停止。为了与 Python 2.x 中的map()完全兼容,请将序列也包装在itertools.zip_longest()中,例如map(func, *sequences)变为list(map(func, itertools.zip_longest(*sequences)))

  • range()现在的行为就像过去的xrange()一样,但它适用于任意大小的值。后者不再存在。

  • zip()现在返回一个迭代器。

Ordering Comparisons

Python 3.0 简化了排序比较的规则:

  • 当操作数没有有意义的自然排序时,排序比较运算符(<<=>=>)引发 TypeError 异常。因此,像1 < ''0 > Nonelen <= len之类的表达式不再有效,例如None < None加注TypeError而不是False返回。结果是,对异构列表进行排序不再有意义-所有元素必须彼此可比。请注意,这不适用于==!=运算符:不同类型的对象始终比较彼此不相等。

  • builtin.sorted()list.sort()不再接受提供比较Function的* cmp 参数。请改用 key *参数。 N.B. * key reverse *参数现在是“仅关键字”。

  • cmp()函数应被视为已消失,并且不再支持__cmp__()特殊方法。根据需要使用lt()进行排序,使用eq()hash()进行其他比较。 (如果确实需要cmp()Function,则可以使用表达式(a > b) - (a < b)等效于cmp(a, b).)

Integers

  • PEP 237:本质上,long重命名为int。也就是说,只有一个内置的整数类型,名为int;但其行为与旧的long类型类似。

  • PEP 238:类似1/2的表达式返回浮点数。使用1//2获得截断行为。 (至少从 Python 2.2 开始,后一种语法已经存在多年了.)

  • 删除了sys.maxint常量,因为整数值不再受限制。但是,sys.maxsize可以用作大于任何实际列表或字符串索引的整数。它符合实现的“自然”整数大小,并且通常与同一平台上的先前版本中的sys.maxint相同(假定具有相同的生成选项)。

  • 长整数的repr()不再包含结尾的L,因此无条件剥离该字符的代码将砍掉最后一位数字。 (改为使用str()。)

  • 八进制 Literals 不再是0720的形式;请改用0o720

Literals 对比。数据而不是 UnicodeVs。 8 位

您认为有关二进制数据和 Unicode 的一切都已更改。

  • Python 3.0 使用* text 和(二进制) data *的概念,而不是 Unicode 字符串和 8 位字符串。所有文本均为 Unicode;但是,编码 Unicode 表示为二进制数据。用于保存文本的类型为str,用于保存数据的类型为bytes。与 2.x 情况最大的不同是,在 Python 3.0 中将文本和数据混合在一起的任何try都会引发TypeError,而如果在 Python 2.x 中将 Unicode 和 8 位字符串混合在一起,则如果使用 8 位,则可以工作字符串恰好只包含 7 位(ASCII)字节,但是如果它包含非 ASCII 值,您将得到UnicodeDecodeError。这些年来,这种特定于价值的行为引起了无数面孔。

  • 由于这种哲学上的变化,几乎所有使用 Unicode,编码或二进制数据的代码都必须更改。所做的更改变得更好,因为在 2.x 世界中,存在许多与混合编码和未编码文本有关的错误。要在 Python 2.x 中进行准备,请开始对所有未编码的文本使用unicode,仅对二进制或编码的数据使用str。然后2to3工具将为您完成大部分工作。

  • 您不能再将u"..."Literals 用作 Unicode 文本。但是,必须对二进制数据使用b"..."Literals。

  • 由于strbytes类型不能混合使用,因此必须始终在它们之间进行显式转换。使用str.encode()strbytes,以及bytes.decode()bytesstr。您也可以分别使用bytes(s, encoding=...)str(b, encoding=...)

  • str一样,bytes类型是不可变的。有一个单独的* mutable *类型可保存缓冲的二进制数据bytearray。几乎所有接受bytes的 API 也都接受bytearray。可变的 API 基于collections.MutableSequence

  • 原始字符串 Literals 中的所有反斜杠均按字面意义进行解释。这意味着未对原始字符串中的'\U''\u'转义进行特殊处理。例如,r'\u20ac'在 Python 3.0 中是 6 个字符的字符串,而在 2.6 中,ur'\u20ac'是单个“欧元”字符。 (当然,此更改仅影响原始字符串 Literals;在 Python 3.0 中,欧元字符为'\u20ac'.)

  • 内置的basestring抽象类型已删除。请改用strstrbytes类型的Function不足以保证共享的 Base Class。 2to3工具(见下文)将每次出现的basestring替换为str

  • 作为文本文件打开的文件(仍然是open()的默认模式)始终使用编码在字符串(在内存中)和字节(在磁盘上)之间 Map。二进制文件(在 mode 参数中以b打开)始终使用内存中的字节。这意味着,如果使用不正确的模式或编码打开文件,则 I/O 可能会大声失败,而不是无声地产生不正确的数据。这也意味着,即使是 Unix 用户,在打开文件时也必须指定正确的模式(文本或二进制)。有一个与平台有关的默认编码,在 Unixy 平台上可以使用LANG环境变量(有时也可以使用其他一些与平台特定的语言环境相关的环境变量)来设置。在许多情况下(但不是全部),系统默认值为 UTF-8.您永远不要指望这个默认值。任何读取或写入的内容不止是纯 ASCII 文本,任何应用程序都应该可以覆盖编码。不再需要在codecs模块中使用可识别编码的流。

  • sys.stdinsys.stdoutsys.stderr的初始值现在是纯 Unicode 文本文件(即,它们是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()返回字符串列表时,将Ellipsis无法正确解码的文件名,而不是引发UnicodeError

  • 当无法使用默认编码解释系统提供的字节时,某些系统 API(例如os.environsys.argv)也会出现问题。设置LANG变量并重新运行程序可能是最好的方法。

  • PEP 3138:字符串的repr()不再转义非 ASCII 字符。但是,在 Unicode 标准中,它仍然转义具有不可打印状态的控制字符和代码点。

  • PEP 3120:现在默认的源编码为 UTF-8.

  • PEP 3131:现在允许在标识符中使用非 ASCII 字母。 (但是,标准库仅保留 ASCII,Comments 中的贡献者名称除外.)

  • StringIOcStringIO模块不见了。而是,导入io模块,并将io.StringIOio.BytesIO分别用于文本和数据。

  • 另请参见Unicode HOWTO,该版本已针对 Python 3.0 更新。

语法更改概述

本节简要概述了 Python 3.0 中的每个语法更改。

New Syntax

  • PEP 3107:函数参数和返回值 Comments。这提供了一种 Comments 函数参数和返回值的标准化方法。除了可以在运行时使用__annotations__属性对它们进行自省外,这些 Comments 没有附加任何语义。目的是鼓励pass元类,装饰器或框架进行实验。

  • PEP 3102:仅关键字参数。必须在调用中使用关键字语法指定在参数列表中*args之后出现的命名参数。您还可以在参数列表中使用裸露的*来表示您不接受可变长度的参数列表,但确实具有仅关键字的参数。

  • 在类定义的 Base Class 列表之后允许使用关键字参数。新约定将其用于指定元类(请参见下一节),但也可以用于其他目的,只要元类支持它即可。

  • PEP 3104nonlocal语句。现在,您可以使用nonlocal x直接分配给外部(但非全局)范围内的变量。 nonlocal是一个新的保留字。

  • PEP 3132:扩展的可迭代拆包。您现在可以编写a, b, *rest = some_sequence之类的东西。甚至*rest, a = stuffrest对象始终是一个(可能为空)列表。右侧可能是任意迭代的。例:

(a, *rest, b) = range(5)

这将* a 设置为0 b 设置为4,而 rest *设置为[1, 2, 3]

  • 字典理解:{k: v for k, v in stuff}dict(stuff)含义相同,但更灵活。 (这是 PEP 274辩护。:-)

  • 设置 Literals,例如{1, 2}。注意{}是一个空字典;将set()用作空集。还支持集合理解;例如{x for x in stuff}的含义与set(stuff)相同,但更灵活。

  • 新的八进制 Literals,例如0o720(早于 2.6)。旧的八进制 Literals(0720)消失了。

  • 新的二进制 Literals,例如0b1010(已在 2.6 中提供),并且有一个相应的新内置函数bin()

  • 字节 Literals 以前导bB引入,并且有一个相应的新内置函数bytes()

Changed Syntax

  • PEP 3109 PEP 3134:新的raise语句语法:raise [expr [from expr]]。见下文。

  • aswith现在是保留字。 (实际上是从 2.6 开始.)

  • TrueFalseNone是保留字。 (2.6 已部分地对None实施了限制.)

  • except * exc var *更改为except * exc * as * var *。参见 PEP 3110

  • PEP 3115:新的元类语法。代替:

class C:
    __metaclass__ = M
    ...

您现在必须使用:

class C(metaclass=M):
    ...

不再支持模块全局__metaclass__变量。 (这使得在不从object派生每个类的情况下,更轻松地默认为新类成为了拐杖。)

  • 列表理解不再支持语法形式[... for var in item1, item2, ...]。改用[... for var in (item1, item2, ...)]。还要注意,列表推导具有不同的语义:对于list()构造函数内部的生成器表达式,它们更接近语法糖,并且尤其是循环控制变量不再泄漏到周围的范围中。

  • Ellipsis号(...)可以在任何地方用作原子表达式。 (以前只能在切片中使用.)而且,它现在必须被拼写为...。 (以前也可能只是出于语法偶然而将其拼写为. . ..)

Removed Syntax

  • PEP 3113:已删除 Tuples 参数解压缩。您不能再写def foo(a, (b, c)): ...。使用def foo(a, b_c): b, c = b_c代替。

  • 删除了反引号(改为使用repr())。

  • 已删除<>(改为使用!=)。

  • 已删除的关键字:exec()不再是关键字;它仍然是一个Function。 (幸运的是,在 2.x 中也接受了函数语法.)还要注意,exec()不再接受流参数;可以使用exec(f.read())代替exec(f)

  • 整数 Literals 不再支持尾随lL

  • 字符串 Literals 不再支持前导uU

  • from * module * import *语法仅在模块级别被允许,而不再在函数内部。

  • 相对导入的唯一可接受语法是from .[module] import name。所有不以.开头的import表单均被解释为绝对导入。 ( PEP 328)

  • 经典类不见了。

Python 2.6 中已经存在的更改

由于许多用户可能会直接从 Python 2.5 过渡到 Python 3.0,因此本节提醒 Reader 一些本来是为 Python 3.0 设计的新Function,但这些新Function已反向移植到 Python 2.6. 有关详细说明,请参考Python 2.6 的新增Function中的相应部分。

Library Changes

由于时间限制,本文档未详尽涵盖标准库的非常广泛的更改。 PEP 3108是对该库进行重大更改的参考。这是胶囊 Comment:

  • 许多旧模块已删除。诸如gopherlib(不再使用)和md5(由hashlib代替)之类的内容已被 PEP 4弃用。由于取消了对 Irix,BeOS 和 Mac OS 9 等各种平台的支持,其他的也被删除(请参阅 PEP 11)。由于缺少使用或存在更好的替代品,因此在 Python 3.0 中也选择了一些模块进行删除。有关详细列表,请参见 PEP 3108

  • 之所以删除了bsddb3软件包,是因为由于测试不稳定和 Berkeley DB 的发布时间表,随着时间的推移证明bsddb3软件包在核心标准库中的存在对核心开发人员来说是特别的负担。但是,该程序包仍然有效,并且外部保持在https://www.jcea.es/programacion/pybsddb.htm

  • 一些模块被重命名是因为其旧名称违反了 PEP 8或出于其他各种原因。这是 Lists:

Old Name New Name
_winreg winreg
ConfigParser configparser
copy_reg copyreg
Queue queue
SocketServer socketserver
markupbase _markupbase
repr reprlib
test.test_support test.support
  • 在 Python 2.x 中,一种常见的模式是拥有一个用纯 Python 实现的模块版本,以及一个作为 C 扩展实现的可选加速版本。例如picklecPickle。这给这些模块的每个用户都带来了导入加速版本并回退到纯 Python 版本的负担。在 Python 3.0 中,加速版本被视为纯 Python 版本的实现细节。用户应始终导入标准版本,该标准版本将try导入加速版本并退回到纯 Python 版本。 pickle/cPickle对接受了这种处理。 profile模块在 3.1 的列表中。 StringIO模块已变成io模块中的类。

  • 一些相关的模块已分组到程序包中,通常子模块的名称已得到简化。产生的新软件包是:

  • dbm ( anydbm , dbhash , dbm, dumbdbm , gdbm , whichdb ).

    • html ( HTMLParser , htmlentitydefs ).

    • http ( httplib , BaseHTTPServer , CGIHTTPServer , SimpleHTTPServer , Cookie , cookielib ).

    • tkinter(除turtle之外的所有Tkinter相关模块)。 turtle的目标受众并不 true 关心tkinter。另请注意,自 Python 2.6 起,turtle的Function已大大增强。

    • urllib (urllib, urllib2 , urlparse , robotparse ).

    • xmlrpc ( xmlrpclib , DocXMLRPCServer , SimpleXMLRPCServer ).

对标准库模块的其他一些更改,但未在 PEP 3108中涵盖:

  • 杀死sets。使用内置的set()类。

  • 清理sys模块:删除了sys.exitfunc()sys.exc_clear()sys.exc_typesys.exc_valuesys.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模块不见了。

  • 为了支持tempfile模块,已删除了Functionos.tmpnam()os.tempnam()os.tmpfile()

  • tokenize模块已更改为使用字节。现在的主要入口点是tokenize.tokenize(),而不是 generate_tokens。

  • string.letters及其朋友(string.lowercasestring.uppercase)不见了。请改用string.ascii_letters等。 (被删除的原因是string.letters和朋友有特定于区域设置的行为,这对于这样具有吸引力的全局“常量”来说是个坏主意.)

  • 将模块__builtin__重命名为builtins(删除下划线,添加“ s”)。在大多数全局名称空间中找到的__builtins__变量未更改。要修改内置函数,您应该使用builtins,而不是__builtins__

PEP 3101:字符串格式化的新方法

  • 用于内置字符串格式化操作的新系统取代了%字符串格式化运算符。 (但是,仍支持%运算符;它将在 Python 3.1 中弃用,并在稍后的时间将其从语言中删除.)请阅读 PEP 3101以获取完整的消息。

exception 变更

用于引发和捕获异常的 API 已被清理,并添加了新的强大Function:

  • PEP 352:必须(直接或间接)派生自BaseException的所有异常。这是异常层次结构的根。这不是新建议,但是从BaseException继承的* requirement *是新的。 (Python 2.6 仍然允许引发经典类,并且对可以捕获的内容没有任何限制.)结果,字符串异常finally true 地彻底消失了。

  • 实际上,几乎所有异常都应源自ExceptionBaseException仅应用作仅应在顶层处理的异常(例如SystemExitKeyboardInterrupt)的 Base Class。除了后一类之外,处理所有异常的建议惯用法是使用except Exception

  • StandardError已被删除。

  • 异常不再表现为序列。请改用args属性。

  • PEP 3109:引发异常。现在,您必须使用raise Exception(args)而不是raise Exception, args。此外,您不再可以显式指定回溯。相反,如果您必须执行此操作,则可以直接分配给__traceback__属性(请参见下文)。

  • PEP 3110:捕获异常。现在,您必须使用except SomeException as variable而不是except SomeException, variable。此外,当保留except块时,会显式删除* variable *。

  • PEP 3134:异常链接。有两种情况:隐式链接和显式链接。当在exceptfinally处理程序块中引发异常时,就会发生隐式链接。这通常是由于处理程序块中的错误导致的。我们将其称为“次要”异常。在这种情况下,原始异常(正在处理的)将保存为次要异常的__context__属性。使用以下语法调用显式链接:

raise SecondaryException() from primary_exception

(其中* primary_exception *是产生异常对象的任何表达式,可能是先前捕获的异常)。在这种情况下,主要 exception 存储在次要 exception 的__cause__属性上。发生未处理的异常时打印的 traceback 遍历__cause____context__属性链,并为链中的每个组件打印一个单独的 traceback,主要 exception 在顶部。 (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_closurefunc_codefunc_defaultsfunc_dictfunc_docfunc_globalsfunc_name分别重命名为__closure____code____defaults__dict__doc____globals__name

  • __nonzero__()现在是bool()

Builtins

  • PEP 3135:新super()。现在,您可以不带参数调用super(),并且(假设这是在class语句中定义的常规实例方法中),将自动选择正确的类和实例。使用自变量时,super()的行为不变。

  • PEP 3111raw_input()重命名为input()。也就是说,新的input()函数从sys.stdin读取一行,并以删除尾随的换行符的形式返回它。如果 Importing 过早终止,它将加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)

  • 已删除callable()。可以使用isinstance(f, collections.Callable)代替callable(f)operator.isCallable()Function也消失了。

  • 已删除coerce()。现在经典类已不存在,此Function不再起作用。

  • 已删除execfile()。代替_使用exec(open(fn).read())

  • 删除了file类型。使用open()。现在,可以在io模块中返回几种打开的流。

  • 已删除reduce()。如果您确实需要,请使用functools.reduce();但是,显式for循环在 99%的时间内可读性更高。

  • 已删除reload()。使用imp.reload()

  • 已移除。 dict.has_key() –使用in运算符。

Build 和 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_OLDARGSWITH_CYCLE_GC

Performance

3.0 概括的finally结果是,Python 3.0 运行 pystone 基准比 Python 2.5 慢约 10%。最可能的最大原因是删除了小整数的特殊 Shell。有改进的空间,但是将在 3.0 发布之后发生!

移植到 Python 3.0

为了将现有的 Python 2.5 或 2.6 源代码移植到 Python 3.0,最佳策略是:

  • (前提:)首先要进行出色的测试。

  • 移植到 Python 2.6. 这应该比从 Python 2.x 到 Python 2.(x 1)的平均端口更多的工作。确保所有测试pass。

  • (仍然使用 2.6 :)打开-3命令行开关。这将启用有关将在 3.0 中删除(或更改)的Function的警告。再次运行您的测试套件,并修复收到警告的代码,直到没有警告出现,并且所有测试仍然pass。

  • 在您的源代码树上运行2to3源到源转换器。 (有关此工具的更多信息,请参见2 to3-自动 Python 2 到 3 代码翻译。)在 Python 3.0 下运行转换结果。手动修复所有剩余的问题,修复问题,直到所有测试再次pass。

不建议try编写在 Python 2.6 和 3.0 下都可以运行的源代码。您必须使用非常扭曲的编码风格,例如避免print语句,元类等。如果要维护一个需要同时支持 Python 2.6 和 Python 3.0 的库,最好的方法是pass编辑 2.6 版本的源代码并再次运行2to3转换器来修改上述步骤 3,而不是编辑该版本的 3.0 版本。源代码。

有关将 C 扩展移植到 Python 3.0 的信息,请参见将扩展模块移植到 Python 3